關(guān)于Sytem.gc()主動(dòng)觸發(fā)Android GC


歡迎訪問Android日記,如有轉(zhuǎn)載請注明Android日記 http://androiddiary.site


2016.12.31 周六 晴 杭州

記錄今天值得閱讀的文章:

  1. 拓展篇:注解處理器最佳實(shí)踐
  2. Glide源碼分析

寫日記

由于想主動(dòng)的通過代碼觸發(fā)gc測試軟引用與弱引用的不同表現(xiàn)擅这,很自然我就想到了去調(diào)用System.gc();既然用到了這個(gè)函數(shù)我就想去看看這個(gè)函數(shù)是怎么樣實(shí)現(xiàn)的

/** * Runs the garbage collector. 
 * Calling the gc method suggests that the Java Virtual
 * Machine expend effort toward recycling unused objects in order to
 * make the memory they currently occupy available for quick reuse.
 * When control returns from the method call, the Java Virtual 
* Machine has made a best effort to reclaim space from all discarded 
* objects.
* The call <code>System.gc()</code> is effectively equivalent to the 
* call: Runtime.getRuntime().gc()
 * * @see     java.lang.Runtime#gc()
 */
public static void gc() { 
   boolean shouldRunGC;
   synchronized (LOCK) {
        shouldRunGC = justRanFinalization;
        if (shouldRunGC) {
            justRanFinalization = false;
        } else {
            runGC = true;
        }
    }
    if (shouldRunGC) {
        Runtime.getRuntime().gc();
    }
}

突然感覺有點(diǎn)不對呢螃概,印象中文檔都說和直接調(diào)用Runtime.getRuntime().gc();一樣的

Paste_Image.png

并且在jdk中也是直接調(diào)用的實(shí)現(xiàn)箩绍。所以由此而想到Google應(yīng)該是在某個(gè)版本更改了Android中的實(shí)現(xiàn)。經(jīng)過查看api19也就是Android 4.4還是沒有變化的

   /**
     * Indicates to the VM that it would be a good time to run the
     * garbage collector. Note that this is a hint only. There is no guarantee
     * that the garbage collector will actually be run.
     */
    public static void gc() {
        Runtime.getRuntime().gc();
    }

而在Android 5.0(API21)之后也就變成了一開始提到的樣子句各。
具體分析一下Google對System.gc()進(jìn)行了怎樣的改變,調(diào)用System.gc只有當(dāng)justRanFinalization 為true的時(shí)候才執(zhí)行一次Runtime.getRuntime().gc();也就是說連續(xù)多次調(diào)用時(shí)不能全部都生效的剔蹋,再看看justRanFinalization 是啥時(shí)候改變的

/**
 * Runs the finalization methods of any objects pending finalization.
 * <p>
 * Calling this method suggests that the Java Virtual Machine expend
 * effort toward running the <code>finalize</code> methods of objects
 * that have been found to be discarded but whose <code>finalize</code>
 * methods have not yet been run. When control returns from the
 * method call, the Java Virtual Machine has made a best effort to
 * complete all outstanding finalizations.
 * <p>
 * The call <code>System.runFinalization()</code> is effectively
 * equivalent to the call:
 * Runtime.getRuntime().runFinalization()
 * * @see     java.lang.Runtime#runFinalization()
 */
public static void runFinalization() {
    boolean shouldRunGC;
    synchronized (LOCK) {
        shouldRunGC = runGC;
        runGC = false;
    }
    if (shouldRunGC) {
        Runtime.getRuntime().gc();
    }
    Runtime.getRuntime().runFinalization();
    synchronized (LOCK) {
        justRanFinalization = true;
    }
}

忽然發(fā)現(xiàn)這個(gè)除了會(huì)改變justRanFinalization 的值幅狮,在 runGC 為true時(shí)調(diào)用這個(gè)方法也會(huì)觸發(fā) Runtime.getRuntime().gc();
讓我們看看justRanFinalization的定義

/**
 * Whether or not we need to do a GC before running the finalizers.
 */
private static boolean runGC;
/**
 * If we just ran finalization, we might want to do a GC to free the finalized objects.
 * This lets us do gc/runFinlization/gc sequences but prevents back to back System.gc().
 */
private static boolean justRanFinalization;

也就是我們 gc/runFinlization/gc 這樣調(diào)用完成一次gcAndFinalize,但是要避免多次反復(fù)的調(diào)用System.gc().

我們可以看一下ZygoteInit中的gcAndFinalize()方法中如何使用的

/**
 * Runs several special GCs to try to clean up a few generations of
 * softly- and final-reachable objects, along with any other garbage.
 * This is only useful just before a fork().
 */
 static void gcAndFinalize() {
    final VMRuntime runtime = VMRuntime.getRuntime();
    /* runFinalizationSync() lets finalizers be called in Zygote,
     * which doesn't have a HeapWorker thread.
     */
    System.gc();
    runtime.runFinalizationSync();
    System.gc();
}

這里的 VMRuntime.getRuntime().runFinalizationSync();的作用其實(shí)和Runtime.getRuntime().runFinalization();作用一樣闯估。Runtime.getRuntime().gc()是告訴垃圾收集器打算進(jìn)行垃圾收集,而垃圾收集器進(jìn)不進(jìn)行收集是不確定的;Runtime.getRuntime().runFinalization();強(qiáng)制調(diào)用已經(jīng)失去引用的對象的finalize方法

讓我們看一下谷歌為什么這樣修改System.gc()這個(gè)方法呢供炼?
從這個(gè)commit

Avoid running Runtime.gc() until we need to run finalization.
This prevents excessive explicit GC which are called from apps to get

good GC behavior on Dalvik. Calling System.gc() does not help on ART
since GC for alloc is much rarer.
If running finalizers is requested following a System.gc we remember
that a GC was requested and perform it ahead of finalization.
Bug: 12004934
Change-Id: Id1343ce8b5378c5f53c1e5649c06ddd045f56a3b

從這里可以得到兩點(diǎn)信息:
1.首先這是為了修復(fù)一個(gè)bug 12004934
2.其次在art模式下一屋,直接調(diào)用gc的效果不大。

參考文章:
System.GC()并不一定執(zhí)行的原因 http://www.eoeandroid.com/thread-922938-1-1.html
Android System.gc()注意點(diǎn)
http://blog.csdn.net/fearGod/article/details/46364599

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末袋哼,一起剝皮案震驚了整個(gè)濱河市冀墨,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌涛贯,老刑警劉巖诽嘉,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異弟翘,居然都是意外死亡虫腋,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進(jìn)店門稀余,熙熙樓的掌柜王于貴愁眉苦臉地迎上來悦冀,“玉大人,你說我怎么就攤上這事睛琳『畜。” “怎么了踏烙?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長历等。 經(jīng)常有香客問我宙帝,道長,這世上最難降的妖魔是什么募闲? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮愿待,結(jié)果婚禮上浩螺,老公的妹妹穿的比我還像新娘。我一直安慰自己仍侥,他們只是感情好要出,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著农渊,像睡著了一般患蹂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上砸紊,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天传于,我揣著相機(jī)與錄音,去河邊找鬼醉顽。 笑死沼溜,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的游添。 我是一名探鬼主播系草,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼唆涝!你這毒婦竟也來了找都?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤廊酣,失蹤者是張志新(化名)和其女友劉穎能耻,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體啰扛,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡嚎京,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了隐解。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鞍帝。...
    茶點(diǎn)故事閱讀 40,427評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖煞茫,靈堂內(nèi)的尸體忽然破棺而出帕涌,到底是詐尸還是另有隱情摄凡,我是刑警寧澤,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布蚓曼,位于F島的核電站亲澡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏纫版。R本人自食惡果不足惜床绪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望其弊。 院中可真熱鬧癞己,春花似錦、人聲如沸梭伐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽糊识。三九已至绩社,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間赂苗,已是汗流浹背愉耙。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留哑梳,地道東北人劲阎。 一個(gè)月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像鸠真,于是被迫代替她去往敵國和親悯仙。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評論 2 359

推薦閱讀更多精彩內(nèi)容