AndroidStudio 內存泄漏的分析過程

前言部分

這次泄漏是自己代碼寫的太隨意引起的,講道理,代碼寫的太爲所欲爲了,導致有些問題根本就很難發現。

泄漏產生的原因,由於activity未被回收導致。這裏給我們提出的一個警示,在使用上下文的時候,我們要特別注意,尤其是一些實例的上下文,如:activity、fragment等。

這次的錯誤原因就是我把activity作爲上下文傳給了Glide使用,結果後期我做夜間模式,需要重啓activity讓夜間模式生效的時候忘記Glide還在持有activity的引用導致了泄漏。

內容部分

產生了泄漏的時候我們需要一些分析工具,leakcanary算是一個必備工具了。我們通過leakcanary可以收集到app產生的泄漏信息,然後通過信息可以找到具體的類,定位到泄漏的類中,在順着引用連接就可以找到了。下面看一個泄漏的圖:

上圖中可以看出一些重要信息:

MainActivity的實例發生了泄漏,這表明我們的MainActivity在實例銷燬的時候由於被Glide引用,並沒有被回收。

導致這個結果的原因就是下面這段代碼:

Glide.with(this@MainActivity)
.load(R.drawable.head_photo)
  .apply(RequestOptions.bitmapTransform(CircleCrop()))
  .into(ivPersonPhoto!!)

這裏傳入Glide中的上下文我沒有使用applicationContext,結果在啓用夜間模式的時候進行重啓activity的時候出現了泄漏。

一些簡單的泄漏通過leakcanary幫助我們收集的信息是可以處理的。但是如果有很多地方都引用一個實例的話,我們就需要使用一下分析工具了。

下面我們來看一下如何通過studio查看泄漏的步驟

  1. 我們先通過操作產生泄漏,這個時候我們的內存已經出現了泄漏。
  2. 然後點擊Profile如圖:在這裏插入圖片描述
  3. 下面我們手動觸發GC來回收無用的內存。如圖:在這裏插入圖片描述
  4. 然後內存不在減少後我們點擊一下小垃圾桶旁邊的箭頭。就可以獲取到內存的情況了。
  5. 我們點擊MainActivity這個類,在右側我們發現有兩個對象在內存中。在這裏插入圖片描述
  6. 點擊後發現MainActivity被GlideRequests引用。如圖

上面基本定位完成,這裏我們在去找Glide引用MainActivity的地方就可以了。

上面講的其實不太實用,因爲實在通過leakcanary中確定MainActivity發生了泄漏,然後去直接去找的MainActivity,並且找到了Glide引用了MainActivity的實例才能順利解決。

實際場景中還有很多複雜的內容,比如我的MainActivity可能被很多地方引用,找起來還是很麻煩的。所以這篇文章也只是最簡單的應用。就像以前我寫的查找應用超時的問題一樣,基本也是找到trace文件,在裏面找到自己項目相關的代碼,在進行定位(猜測)。

結語部分

很多人都會問怎麼進行內存泄漏的排查,其實我覺得更多的還是看經驗了。因爲有些泄漏真的是很難發現,如果是偶然纔會發生的泄漏,那就真的更難查找了。

多學習積累一些經驗會更好的幫助我們處理一些比較詭異的問題

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章