說明:如果隻是單存的記憶體抖動,AndroidStudio的Memory Profiler就可以分析了,具體分析過程已經有很多文章說明了,這裡就不贅述,接下來要說的是記憶體洩露的追查。
1.MAT下載下傳
MAT 下載下傳位址:https://www.eclipse.org/mat/downloads.php
下載下傳版本:
Mac OSX (Mac/Cocoa/x86_64)
2.MAT安裝和啟動
下載下傳完成,在Downloads目錄下找到
MemoryAnalyzer-1.9.0.20190605-macosx.cocoa.x86_64.zip
。
解壓檔案,得到
mat.app
目錄。移動到自己的目錄下執行 /xxxxx/mat.app/Contents/MacOS/MemoryAnalyzer -data ./workspace
輸入指令行 : /Users/mac/Desktop/mat/mat.app/Contents/MacOS/MemoryAnalyzer -data ./workspace
看到歡迎界面就是成功了。
這是一款用于記憶體分析的工具,主要可以對記憶體洩露(OOM之前)的問題進行分析和定位。配合Memory Profiler分析記憶體洩露導緻的卡頓和線上偶發性的崩潰。
由于我們的app中有一些寫的不合适的代碼片段,導緻記憶體的配置設定非常頻繁,在頻繁的配置設定和GC的情況下就會出現記憶體抖動。當我們使用static不注意的時候就很容易造成 對外部類的強引用,即使不調用不崩潰,但是由于static和app的生命周期相同,是以強引用的對象無法釋放,導緻記憶體無法清理,由于每一個app所配置設定的記憶體是有限的,是以就會導緻記憶體洩露,當洩露到一定程度,剩餘記憶體或者記憶體碎片不足以配置設定的時候就會OOM,崩潰,這就是線上崩潰線下無法複現的問題的來源。
分析步驟:
1.當我們看到頁面卡頓
比如我們建立一個回調,内部包含static靜态變量,然後裡面也傳入了Context,假設在Activity的OnClick時間内構造它,那麼每一次構造都會有Context - XXXActivity對象被儲存在這個回調的内部,那麼每一次finish都不會釋放。
當我們打開AndroidStudio的Memory Profiler的時候我們就可以在Memory裡面看到成階梯狀的記憶體消耗的趨勢。這個時候我們通過記憶體變化曲線(階梯狀)可以判斷記憶體存在洩漏。
我們隻需要把我們認為有洩漏的部分,進行堆轉儲,導出檔案即可
(華為手機 eg P40,當我們使用Memory Profiler的時候會閃退,可能是ROM架構的問題)
接下來,将導出檔案轉換:
hprof-conv /xxxx/memory_leak.hprof /xxxxx/memory_leak_transed.hprof 不執此指令MAT不能處理堆轉儲檔案
1.打開檔案
點選Histogram
2.比對搜尋需要的類的名稱
我們可以看見有一個Activity存在存在七個對象 這是不合理的
那麼來看看都是誰強引用了吧
看見了七個強引用
選擇一個對象 去除軟引用 隻關注強引用 也可以直接看with all references
檢視強引用結果的依賴路徑
我們可以看見是EventBus中持有了上下文的引用看看源碼
銷毀的時候寫錯了,應該改成
@Override
protected void onDestroy() {
super.onDestroy();
if (EventBus.getDefault().isRegistered(this)) {
//取消注冊
EventBus.getDefault().unregister(this);
}
}
這樣就釋放了。雖然隻是一個複制粘貼的問題,但是卻真實的影響了性能,不會崩潰,線上上是一個很惡心的bug,回報到研發這裡隻是偶現。這就是通過記憶體分析查找問題的方法 MAT+MemoryProfiler
前後對比
可以看見記憶體得到了釋放~~~~~~~~