KOOM(Kwai OOM, Kill OOM)是快手性能優化團隊在處理移動端OOM問題的過程中沉淀出的一套完整解決方案。其中Android Java內存部分在LeakCanary的基礎上進行了大量優化,解決了線上內存監控的性能問題,在不影響用戶體驗的前提下線上采集內存鏡像並解析。
一、KOOM 背景
隨着移動端業務邏輯日益復雜,4K編解碼、AR魔表等高內存需求場景的逐漸普及,OOM問題已成為快手客戶端穩定性治理的頭號頑疾。 在日常版本迭代過程中,間或會發生OOM激增,而線上環境非常復雜,僅AB實驗就有上千種,事前預防以及事后還原都無法做到,因此急需高性能的線上內存監控方案。一期開源的Android Java內存監控方案,我們調研了LeakCanary以及美團和UC等發表的相關技術文章,發現業內的優化方向主要集中在內存鏡像的解析部分,而內存鏡像dump部分,一直沒有方案能解決dump過程中app長時間凍結的問題。經過深入研究,我們發現可以利用Copy-on-write機制fork子進程dump,滿足我們的需求。
二、KOOM 指南
1. 運行demo
首先建議跑通一下項目自帶demo(koom-demo項目),對KOOM提供的基礎功能和概念有一個大致的了解。
2. 依賴接入
dependencies { implementation 'com.kwai.koom:java-oom:1.0.4' }
3. 初始化
Application初始化:
public class KOOMApplication extends Application { @Override public void onCreate() { super.onCreate(); KOOM.init(this); } }
4. Java-oom 報告獲取
當內存使用異常,觸發內存鏡像采集並分析后,會生成一份json格式的報告。
可以擇機主動獲取:
public void getReportManually() { File reportDir = new File(KOOM.getInstance().getReportDir()); for (File report : reportDir.listFiles()) { // Upload the report or do something else. } }
也可以實時監聽報告生成狀態:
public void listenReportGenerateStatus() { KOOM.getInstance().setHeapReportUploader(file -> { // Upload the report or do something else. // File is deleted automatically when callback is done by default. }); }
5. Java-oom 組件介紹
內存監控組件 定時采集內存資源占用情況,超過閾值觸發內存鏡像采集,決定鏡像dump與分析時機,關鍵代碼參考Monitor.java
內存鏡像采集組件 高性能內存鏡像采集組件,包含fork dump和strip dump兩個部分,關鍵代碼參考HeapDumper.java
內存鏡像解析組件 高性能內存鏡像解析組件,基於shark解析器定制優化,泄露判定關鍵代碼參考LeakDetector.java