日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

内存泄露(十)-- KOOM(高性能线上内存监控方案)

發(fā)布時(shí)間:2024/1/18 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 内存泄露(十)-- KOOM(高性能线上内存监控方案) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

KOOM介紹
OOMMonitor 介紹
KOOM線上APM監(jiān)控最全剖析
一文看懂快手KOOM高性能監(jiān)控方案
KOOM 淺析
【開源庫(kù)剖析】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)化團(tuán)隊(duì)在處理移動(dòng)端OOM問題的過程中沉淀出的一套完整解決方案。

KOOM 功能

Koom流程:

OOM問題原因分類

  • Java堆內(nèi)存溢出
  • 無足夠連續(xù)內(nèi)存空間
  • FD(文件描述符)超出限制
  • 線程數(shù)量超出限制
  • 虛擬內(nèi)存不足
  • 1. Java Heap 泄漏監(jiān)控

    ??koom-java-leak 模塊用于 Java Heap 泄漏監(jiān)控:它利用 Copy-on-write 機(jī)制 fork 子進(jìn)程 dump Java Heap,解決了 dump 過程中 app 長(zhǎng)時(shí)間凍結(jié)的問題

    • fork子進(jìn)程去執(zhí)行dumpHprofData方法
    • fork進(jìn)程采用的是“Copy On Write”技術(shù),只有在進(jìn)行寫入操作時(shí),才會(huì)為子進(jìn)程拷貝分配獨(dú)立的內(nèi)存空間,默認(rèn)情況下,子進(jìn)程可以和父進(jìn)程共享同個(gè)內(nèi)存空間,所以,當(dāng)我們要執(zhí)行dumpHprofData方法時(shí),可以先fork一個(gè)子進(jìn)程,它擁有父進(jìn)程的內(nèi)存副本,然后在子進(jìn)程中執(zhí)行dumpHprofData方法,而父進(jìn)程則可以正常繼續(xù)運(yùn)行。

      ??hprof是基于JVMTI實(shí)現(xiàn)的內(nèi)存分析器代理,其轉(zhuǎn)儲(chǔ)文件記錄了Java的內(nèi)存鏡像(Heap Profile),其中記錄了內(nèi)存堆詳細(xì)的使用信息,可用于分析Java程序內(nèi)存的各種性能問題。
      ??虛擬機(jī)提供的Debug.dumpHprofData可以將hprof文件輸出在指定的文件中,但是這個(gè)過程會(huì)“凍結(jié)”整個(gè)應(yīng)用進(jìn)程,造成數(shù)秒甚至數(shù)十秒內(nèi)用戶無法操作,即dump文件也是會(huì)產(chǎn)生STW(Stop the world),跟GC一樣會(huì)讓所有線程掛起。

    HeapMonitor.java

    public boolean isTrigger() {if (!started) {return false;}HeapStatus heapStatus = currentHeapStatus();if (heapStatus.isOverMaxThreshold) {// 已達(dá)到最大閥值,強(qiáng)制觸發(fā)trigger,防止后續(xù)出現(xiàn)大內(nèi)存分配導(dǎo)致OOM進(jìn)程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()) {// 第一次進(jìn)來 或者 當(dāng)前內(nèi)存占用率跟上次高 或者 當(dāng)前內(nèi)存占用率超過了最大的閾值(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中設(shè)置了五種檢測(cè)器
    ① HeapOOMTracker
    ② ThreadOOMTracker
    ③ FdOOMTracker
    ④ PhysicalMemoryOOMTracker
    ⑤ FastHugeMemoryOOMTracker
    前三種稱為長(zhǎng)期高內(nèi)存檢測(cè)器,檢測(cè)機(jī)制是當(dāng)計(jì)算出內(nèi)存占用率之后,我們看下面的一個(gè)判斷條件,如果內(nèi)存占用率超過我們?cè)O(shè)定的一個(gè)閾值(例如0.8),而且當(dāng)前內(nèi)存占用率跟上次比較超過了千分之5,那么mOverThresholdCount變量就會(huì)自增1。

    Heap監(jiān)測(cè)機(jī)制是第一次進(jìn)來 或者 當(dāng)前內(nèi)存占用率跟上次高 或者
    當(dāng)前內(nèi)存占用率超過了最大的閾值(95%),三個(gè)條件只要滿足一個(gè),那么mOverThresholdCount變量就會(huì)自增1

    ??因?yàn)闄z測(cè)是一個(gè)循環(huán)的過程,所以當(dāng)?shù)谝淮芜M(jìn)來的時(shí)候,一定會(huì)自增1,而且會(huì)將本次的內(nèi)存占用率賦值給mLastHeapRatio,當(dāng)下次進(jìn)來的時(shí)候,如果內(nèi)存占用率較上次降低了,那么就會(huì)重置。
    ??如此往復(fù),當(dāng)mOverThresholdCount超出我們?cè)O(shè)置的閾值(例如3次),我們就認(rèn)定系統(tǒng)發(fā)生了內(nèi)存泄漏,這個(gè)時(shí)候就需要告警,并dump內(nèi)存快照分析問題。
    1)內(nèi)存占用超過80%,2)并且檢測(cè)到了3次,兩個(gè)條件同時(shí)滿足就會(huì)進(jìn)行dump。
    第四種代碼中返回false沒有進(jìn)行處理。
    第五種稱為高危內(nèi)存與快速增長(zhǎng)檢測(cè)器,檢測(cè)機(jī)制是內(nèi)存占用超過90%或者本次檢測(cè)與上次檢測(cè)內(nèi)存占用超過350M,滿足兩個(gè)條件之一就會(huì)進(jìn)行dump。

    1.1 OOMMonitor 介紹

    用于監(jiān)控應(yīng)用的 Java 內(nèi)存泄漏問題,它的核心原理:

    • 周期性查詢Java堆內(nèi)存、線程數(shù)、文件描述符數(shù)等資源占用情況,當(dāng)連續(xù)多次超過設(shè)定閾值或突發(fā)性連續(xù)快速突破高閾值時(shí),觸發(fā)鏡像采集
    • 鏡像采集采用虛擬機(jī)supend->fork虛擬機(jī)進(jìn)程->虛擬機(jī)resume->dump內(nèi)存鏡像的策略,將傳統(tǒng)Dump凍結(jié)進(jìn)程20s的時(shí)間縮減至20ms以內(nèi)
    • 基于shark執(zhí)行鏡像解析,并針對(duì)shark做了一系列調(diào)整用于提升性能,在手機(jī)設(shè)備測(cè)即可執(zhí)行離線內(nèi)存泄露判定與引用鏈查找,生成分析報(bào)告

    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 機(jī)制分析整個(gè) Native Heap,直接輸出泄漏內(nèi)存信息「大小、分配堆棧等』;極大的降低了業(yè)務(wù)同學(xué)分析、解決內(nèi)存泄漏的成本。

    思路總結(jié):

    • hook malloc/free等內(nèi)存分配器方法,用于記錄Native內(nèi)存分配元數(shù)據(jù)[大小、堆棧、地址等]–使用了愛奇藝的xhook庫(kù)
    • 周期性的使用mark-and-sweep分析整個(gè)進(jìn)程N(yùn)ative Heap, 獲取不可達(dá)的內(nèi)存塊信息[地址、大小]–使用到google的libmemunreachable庫(kù)
    • 利用不可達(dá)的內(nèi)存塊的地址、大小等從我們記錄的元數(shù)據(jù)中獲取其分配堆棧,產(chǎn)出泄漏數(shù)據(jù)[不可達(dá)內(nèi)存地址、大小、分配堆棧等]

    2.1 LeakMonitor 介紹

    用于監(jiān)控應(yīng)用的 Native 內(nèi)存泄漏問題,它的核心原理如下:

    • hook malloc/free 等內(nèi)存分配器方法,用于記錄 Native 內(nèi)存分配元數(shù)據(jù)「大小、堆棧、地址等」
    • 周期性的使用 mark-and-sweep 分析整個(gè)進(jìn)程 Native Heap,獲取不可達(dá)的內(nèi)存塊信息「地址、大小」
    • 利用不可達(dá)的內(nèi)存塊的地址、大小等從我們記錄的元數(shù)據(jù)中獲取其分配堆棧,產(chǎn)出泄漏數(shù)據(jù)「不可達(dá)內(nèi)存塊地址、大小、分配堆棧等」

    2.2 LeakMonitor 適用范圍

    • Android N 及以上(API level >= 24)
    • 僅支持 arm64-v8a

    2.3 LeakMonitor 接入

    LeakMonitor 接入

    3. Thread 泄漏監(jiān)控

    ??koom-thread-leak 模塊用于 Thread 泄漏監(jiān)控:它會(huì) hook 線程的生命周期函數(shù),周期性的上報(bào)泄漏線程信息。

    3.1 ThreadLeakMonitor 介紹

    用于監(jiān)控應(yīng)用的線程泄漏問題,它的核心原理:

    • hook pthread_create/pthread_exit 等線程方法,用于記錄線程的生命周期和創(chuàng)建堆棧,名稱等信息
    • 當(dāng)發(fā)現(xiàn)一個(gè)joinable的線程在沒有detach或者join的情況下,執(zhí)行了pthread_exit,則記錄下泄露線程信息
    • 當(dāng)線程泄露時(shí)間到達(dá)配置設(shè)置的延遲期限的時(shí)候,上報(bào)線程泄露信息

    3.2 ThreadLeakMonitor 適用范圍

    • Android N 及以上(API level >= 24)
    • 僅支持 arm64-v8a

    3.3 ThreadLeakMonitor 接入

    ThreadLeakMonitor 接入

    總結(jié)

    以上是生活随笔為你收集整理的内存泄露(十)-- KOOM(高性能线上内存监控方案)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。