[Android檢查內存泄漏工具Leakcanary] 判斷泄漏原理分析

Leakcanary作用:

  1. 判斷是否有內存泄漏;

  2. 定位并dump出調用棧;

    利用haha庫去輸出dump信息的舆驶。

    haha庫相關信息:https://github.com/square/haha

  3. 以圖形方式展示給開發(fā)者;

    更多Leakcanary信息參考:https://github.com/square/leakcanary

今天我們主要談一下他判斷內存泄漏的方式,也就是上面的第一項筐摘。

說明:

  1. 利用AndroidApplicationandroid.app.Application.ActivityLifecycleCallbacks回調,跟蹤Activity的生命周期壳快,在有android.app.Application.ActivityLifecycleCallbacks.onActivityDestroyed(Activity)的回調時把Activity對象添加到java.lang.ref.WeakReference中老速。

  2. 當添加的對象變?yōu)槿跻镁蜁砑拥?code>java.lang.ref.WeakReference.WeakReference(T, ReferenceQueue<? super T>)的第二個參數,弱引用隊列中御滩。

  3. 利用WeakReference的這一特性,在有onActivityDestroyed回調時党远,通過Runtime.getRuntime().gc()去通知系統(tǒng)gc削解,等待100ms,然后通過java.lang.System.runFinalization()方法沟娱,強制調用已經沒有被引用的對象的java.lang.Object.finalize()方法氛驮。

  4. 檢查WeakReference的第二個參數ReferenceQueue隊列,取出要檢查的Activity济似。 判斷是否在隊列中:

    1. 如果存在:當前對象已變成弱引用矫废,內存可以成功釋放,也就不會有內存泄漏的問題

    2. 如果不存在:說明當前對象目前還被其他對象保持持有關系(有其他對象指向要釋放的對象)砰蠢,沒有按預期釋放當前對象蓖扑,代表這個對象被泄漏了。這種情況積累下來台舱,就會帶來OutOfMemoryError律杠。

      ?

Demo

package com.xinghui.java.weakreference;

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * 
 * @author xinghui
 *
 */
public class WeakReferenceTest {
    
    /**
     * 用于看驗證效果。
     * true: 最后有不能回收的內存
     * false: 內存全部回收
     */
    private static final boolean CONFIG_LEAK = true;
    
    /**
     * 被保留的對象列表
     */
    static Set<Object> retainedObject; 
    
    
    static ReferenceQueue<ClassA> queue = new ReferenceQueue<ClassA>();

    public static void main(String[] args) {
        
        retainedObject = new CopyOnWriteArraySet<Object>();
        
        ClassA mClassA = new ClassA();
        ClassB mClassB = new ClassB();
        mClassB.mClassA = mClassA;
        if (CONFIG_LEAK) {
            ClassC.container = mClassB;
        }
        
        /**
         * 當mClassA變成弱引用時,會添加到queue隊列
         * A WeakReference may be cleared and enqueued as soon as is known to be weakly-referenced.
         */
        WeakReference<ClassA> re = new WeakReference<ClassA>(mClassA, queue);
        retainedObject.add(re);
        mClassA = null;
        mClassB = null;
        
        removeWeaklyReachableReferences("NONE");
        
        /**
         * 1柜去、Java中的System.gc()和Android中的System.gc()是有區(qū)別的灰嫉;
         * @see 2、libcore.java.lang.ref.FinalizationTester.induceFinalization()
         * 
         */
        // System.gc() does not garbage collect every time. Runtime.gc() is
        // more likely to perfom a gc.
        Runtime.getRuntime().gc();// 通知系統(tǒng)gc
        
        try {
            /*
             * Hack. We don't have a programmatic way to wait for the reference queue
             * daemon to move references to the appropriate queues.
             */
            Thread.sleep(100);
        } catch (InterruptedException e) {
            throw new AssertionError();
        }
        System.runFinalization(); // 強制調用*已經沒有被引用的對象*的finalize方法
        
        removeWeaklyReachableReferences("runFinalization");
        
        if (retainedObject.size() > 0) {
            for (Object o : retainedObject) {
                System.out.println("++++++++++ retained Object " + o);
            }
        } else {
            System.out.println("------------NO retained Object");
        }
    }
    
    private static void removeWeaklyReachableReferences(String TAG) {
        
        Reference<? extends ClassA> ref;
        System.out.println(TAG + " start ");
        while ((ref = queue.poll()) != null) {
            retainedObject.remove(ref);
            System.out.println("removed " + ref + " after " + TAG);
        }
    }
    
    static class ClassA {
    }

    static class ClassB {
        ClassA mClassA;
    }

    static class ClassC {
        static ClassB container;
    }
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末嗓奢,一起剝皮案震驚了整個濱河市讼撒,隨后出現的幾起案子,更是在濱河造成了極大的恐慌股耽,老刑警劉巖椿肩,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異豺谈,居然都是意外死亡,警方通過查閱死者的電腦和手機贡这,發(fā)現死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門茬末,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人盖矫,你說我怎么就攤上這事丽惭。” “怎么了辈双?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵责掏,是天一觀的道長。 經常有香客問我湃望,道長换衬,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任证芭,我火速辦了婚禮瞳浦,結果婚禮上,老公的妹妹穿的比我還像新娘废士。我一直安慰自己叫潦,他們只是感情好,可當我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布官硝。 她就那樣靜靜地躺著矗蕊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪氢架。 梳的紋絲不亂的頭發(fā)上傻咖,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天,我揣著相機與錄音达箍,去河邊找鬼没龙。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的硬纤。 我是一名探鬼主播解滓,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼筝家!你這毒婦竟也來了洼裤?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤溪王,失蹤者是張志新(化名)和其女友劉穎腮鞍,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體莹菱,經...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡移国,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了道伟。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片迹缀。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蜜徽,靈堂內的尸體忽然破棺而出祝懂,到底是詐尸還是另有隱情,我是刑警寧澤拘鞋,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布砚蓬,位于F島的核電站,受9級特大地震影響盆色,放射性物質發(fā)生泄漏灰蛙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一傅事、第九天 我趴在偏房一處隱蔽的房頂上張望缕允。 院中可真熱鬧,春花似錦蹭越、人聲如沸障本。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽驾霜。三九已至,卻和暖如春买置,著一層夾襖步出監(jiān)牢的瞬間粪糙,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工忿项, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蓉冈,地道東北人城舞。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像寞酿,于是被迫代替她去往敵國和親家夺。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內容

  • 前言 你被概率性的 OOM 困擾么伐弹?有時候拉馋,OOM 像幽靈一樣,揮之不去惨好,可真想把它揪出來時煌茴,又捉之不著∪沾ǎ或許蔓腐,是...
    kamidox閱讀 40,249評論 13 71
  • 內存管理的目的就是讓我們在開發(fā)中怎么有效的避免我們的應用出現內存泄漏的問題。內存泄漏大家都不陌生了龄句,簡單粗俗的講合住,...
    宇宙只有巴掌大閱讀 2,361評論 0 12
  • Android 內存泄漏總結 內存管理的目的就是讓我們在開發(fā)中怎么有效的避免我們的應用出現內存泄漏的問題。內存泄漏...
    apkcore閱讀 1,219評論 2 7
  • 內存管理的目的就是讓我們在開發(fā)中怎么有效的避免我們的應用出現內存泄漏的問題撒璧。內存泄漏大家都不陌生了,簡單粗俗的講笨使,...
    DreamFish閱讀 791評論 0 5
  • 塊級元素和行內元素分別有哪些卿樱?動手測試并列出4條以上的特性區(qū)別 Block level(塊級元素)div h1 ...
    Klart閱讀 131評論 0 0