LeakCannary 的主要原理糯而,其實(shí)很簡(jiǎn)單北戏,大概可以分為以下幾步:
((1) 監(jiān)測(cè)Activity 的生命周期的 onDestroy() 的調(diào)用。
(2) 當(dāng)某個(gè) Activity 的 onDestroy() 調(diào)用后,便對(duì)這個(gè) activity 創(chuàng)建一個(gè)帶 ReferenceQueue 的弱引用察皇,并且給這個(gè)弱引用創(chuàng)建了一個(gè) key 保存在 Set集合 中。
(3) 如果這個(gè) activity 可以被回收泽台,那么弱引用就會(huì)被添加到 ReferenceQueue 中什荣。
(4) 等待主線程進(jìn)入 idle(即空閑)后,通過一次遍歷怀酷,在 ReferenceQueue 中的弱引用所對(duì)應(yīng)的 key 將從 retainedKeys 中移除稻爬,說明其沒有內(nèi)存泄漏。
(5) 如果 activity 沒有被回收蜕依,先強(qiáng)制進(jìn)行一次 gc桅锄,再來檢查琉雳,如果 key 還存在 retainedKeys 中,說明 activity 不可回收友瘤,同時(shí)也說明了出現(xiàn)了內(nèi)存泄漏翠肘。
(6) 發(fā)生內(nèi)存泄露之后,dump內(nèi)存快照辫秧,分析 hprof 文件束倍,找到泄露路徑(使用 haha 庫分析),發(fā)送到通知欄
LeakCanary對(duì)于內(nèi)存泄漏的檢測(cè)非常有效茶没,但也并不是所有的內(nèi)存泄漏都能檢測(cè)出來肌幽。
<1>無法檢測(cè)出Service中的內(nèi)存泄漏問題
<2>如果最底層的MainActivity一直未走onDestroy生命周期(它在Activity棧的最底層),無法檢測(cè)出它的調(diào)用棧的內(nèi)存泄漏抓半。
所以說LeakCanary針對(duì)Activity/Fragment的內(nèi)存泄漏檢測(cè)非常好用喂急,但是對(duì)于以上檢測(cè)不到的情況,還得配合Android Monitor + MAT 來分析笛求。