内存泄露(十)-- KOOM(高性能线上内存监控方案)
KOOM介紹
OOMMonitor 介紹
KOOM線上APM監(jiān)控最全剖析
一文看懂快手KOOM高性能監(jiān)控方案
KOOM 淺析
【開源庫剖析】KOOM V1.0.5 源碼解析
目錄
- KOOM 功能
- 1. Java Heap 泄漏監(jiān)控
- 1.1 OOMMonitor 介紹
- 1.2 OOMMonitor 適用范圍
- 1.3 OOMMonitor 接入
- 2. Native Heap 泄漏監(jiān)控
- 2.1 LeakMonitor 介紹
- 2.2 LeakMonitor 適用范圍
- 2.3 LeakMonitor 接入
- 3. Thread 泄漏監(jiān)控
- 3.1 ThreadLeakMonitor 介紹
- 3.2 ThreadLeakMonitor 適用范圍
- 3.3 ThreadLeakMonitor 接入
??KOOM(Kwai OOM, Kill OOM)是快手性能優(yōu)化團隊在處理移動端OOM問題的過程中沉淀出的一套完整解決方案。
KOOM 功能
Koom流程:
OOM問題原因分類
1. Java Heap 泄漏監(jiān)控
??koom-java-leak 模塊用于 Java Heap 泄漏監(jiān)控:它利用 Copy-on-write 機制 fork 子進程 dump Java Heap,解決了 dump 過程中 app 長時間凍結的問題
- fork子進程去執(zhí)行dumpHprofData方法
- fork進程采用的是“Copy On Write”技術,只有在進行寫入操作時,才會為子進程拷貝分配獨立的內存空間,默認情況下,子進程可以和父進程共享同個內存空間,所以,當我們要執(zhí)行dumpHprofData方法時,可以先fork一個子進程,它擁有父進程的內存副本,然后在子進程中執(zhí)行dumpHprofData方法,而父進程則可以正常繼續(xù)運行。
??hprof是基于JVMTI實現(xiàn)的內存分析器代理,其轉儲文件記錄了Java的內存鏡像(Heap Profile),其中記錄了內存堆詳細的使用信息,可用于分析Java程序內存的各種性能問題。
??虛擬機提供的Debug.dumpHprofData可以將hprof文件輸出在指定的文件中,但是這個過程會“凍結”整個應用進程,造成數(shù)秒甚至數(shù)十秒內用戶無法操作,即dump文件也是會產生STW(Stop the world),跟GC一樣會讓所有線程掛起。
HeapMonitor.java
public boolean isTrigger() {if (!started) {return false;}HeapStatus heapStatus = currentHeapStatus();if (heapStatus.isOverMaxThreshold) {// 已達到最大閥值,強制觸發(fā)trigger,防止后續(xù)出現(xiàn)大內存分配導致OOM進程Crash,無法觸發(fā)triggerKLog.i(TAG, "heap used is over max ratio, force trigger and over times reset to 0");currentTimes = 0;return true;}if (heapStatus.isOverThreshold) {KLog.i(TAG, "heap status used:" + heapStatus.used / KConstants.Bytes.MB+ ", max:" + heapStatus.max / KConstants.Bytes.MB+ ", last over times:" + currentTimes);if (heapThreshold.ascending()) {// 第一次進來 或者 當前內存占用率跟上次高 或者 當前內存占用率超過了最大的閾值(95%)if (lastHeapStatus == null || heapStatus.used >= lastHeapStatus.used || heapStatus.isOverMaxThreshold) {currentTimes++;} else {KLog.i(TAG, "heap status used is not ascending, and over times reset to 0");currentTimes = 0;}} else {currentTimes++;}} else {currentTimes = 0;}lastHeapStatus = heapStatus;return currentTimes >= heapThreshold.overTimes();}Koom中設置了五種檢測器
① HeapOOMTracker
② ThreadOOMTracker
③ FdOOMTracker
④ PhysicalMemoryOOMTracker
⑤ FastHugeMemoryOOMTracker
前三種稱為長期高內存檢測器,檢測機制是當計算出內存占用率之后,我們看下面的一個判斷條件,如果內存占用率超過我們設定的一個閾值(例如0.8),而且當前內存占用率跟上次比較超過了千分之5,那么mOverThresholdCount變量就會自增1。
Heap監(jiān)測機制是第一次進來 或者 當前內存占用率跟上次高 或者
當前內存占用率超過了最大的閾值(95%),三個條件只要滿足一個,那么mOverThresholdCount變量就會自增1
??因為檢測是一個循環(huán)的過程,所以當?shù)谝淮芜M來的時候,一定會自增1,而且會將本次的內存占用率賦值給mLastHeapRatio,當下次進來的時候,如果內存占用率較上次降低了,那么就會重置。
??如此往復,當mOverThresholdCount超出我們設置的閾值(例如3次),我們就認定系統(tǒng)發(fā)生了內存泄漏,這個時候就需要告警,并dump內存快照分析問題。
即 1)內存占用超過80%,2)并且檢測到了3次,兩個條件同時滿足就會進行dump。
第四種代碼中返回false沒有進行處理。
第五種稱為高危內存與快速增長檢測器,檢測機制是內存占用超過90%或者本次檢測與上次檢測內存占用超過350M,滿足兩個條件之一就會進行dump。
1.1 OOMMonitor 介紹
用于監(jiān)控應用的 Java 內存泄漏問題,它的核心原理:
- 周期性查詢Java堆內存、線程數(shù)、文件描述符數(shù)等資源占用情況,當連續(xù)多次超過設定閾值或突發(fā)性連續(xù)快速突破高閾值時,觸發(fā)鏡像采集
- 鏡像采集采用虛擬機supend->fork虛擬機進程->虛擬機resume->dump內存鏡像的策略,將傳統(tǒng)Dump凍結進程20s的時間縮減至20ms以內
- 基于shark執(zhí)行鏡像解析,并針對shark做了一系列調整用于提升性能,在手機設備測即可執(zhí)行離線內存泄露判定與引用鏈查找,生成分析報告
1.2 OOMMonitor 適用范圍
-
Android L 及以上(API level >= 21)
-
支持 armeabi-v7a arm64-v8a x86 x86-64
1.3 OOMMonitor 接入
OOMMonitor 接入
2. Native Heap 泄漏監(jiān)控
??koom-native-leak 模塊用于 Native Heap 泄漏監(jiān)控:它利用 Tracing garbage collection 機制分析整個 Native Heap,直接輸出泄漏內存信息「大小、分配堆棧等』;極大的降低了業(yè)務同學分析、解決內存泄漏的成本。
思路總結:
- hook malloc/free等內存分配器方法,用于記錄Native內存分配元數(shù)據(jù)[大小、堆棧、地址等]–使用了愛奇藝的xhook庫
- 周期性的使用mark-and-sweep分析整個進程Native Heap, 獲取不可達的內存塊信息[地址、大小]–使用到google的libmemunreachable庫
- 利用不可達的內存塊的地址、大小等從我們記錄的元數(shù)據(jù)中獲取其分配堆棧,產出泄漏數(shù)據(jù)[不可達內存地址、大小、分配堆棧等]
2.1 LeakMonitor 介紹
用于監(jiān)控應用的 Native 內存泄漏問題,它的核心原理如下:
- hook malloc/free 等內存分配器方法,用于記錄 Native 內存分配元數(shù)據(jù)「大小、堆棧、地址等」
- 周期性的使用 mark-and-sweep 分析整個進程 Native Heap,獲取不可達的內存塊信息「地址、大小」
- 利用不可達的內存塊的地址、大小等從我們記錄的元數(shù)據(jù)中獲取其分配堆棧,產出泄漏數(shù)據(jù)「不可達內存塊地址、大小、分配堆棧等」
2.2 LeakMonitor 適用范圍
- Android N 及以上(API level >= 24)
- 僅支持 arm64-v8a
2.3 LeakMonitor 接入
LeakMonitor 接入
3. Thread 泄漏監(jiān)控
??koom-thread-leak 模塊用于 Thread 泄漏監(jiān)控:它會 hook 線程的生命周期函數(shù),周期性的上報泄漏線程信息。
3.1 ThreadLeakMonitor 介紹
用于監(jiān)控應用的線程泄漏問題,它的核心原理:
- hook pthread_create/pthread_exit 等線程方法,用于記錄線程的生命周期和創(chuàng)建堆棧,名稱等信息
- 當發(fā)現(xiàn)一個joinable的線程在沒有detach或者join的情況下,執(zhí)行了pthread_exit,則記錄下泄露線程信息
- 當線程泄露時間到達配置設置的延遲期限的時候,上報線程泄露信息
3.2 ThreadLeakMonitor 適用范圍
- Android N 及以上(API level >= 24)
- 僅支持 arm64-v8a
3.3 ThreadLeakMonitor 接入
ThreadLeakMonitor 接入
總結
以上是生活随笔為你收集整理的内存泄露(十)-- KOOM(高性能线上内存监控方案)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java基于JSP野生动物保护网
- 下一篇: ”下载到itunes的软件不能同步到ip