導(dǎo)語(yǔ)
曾幾何時(shí),我們一直糾結(jié)于到底要不要手動(dòng)調(diào)用System.gc(),有的人說(shuō)這樣調(diào)用太丑陋,完全沒(méi)必要,JVM會(huì)幫我們處理好的,有的人說(shuō)可以調(diào)用,這樣可以及時(shí)釋放內(nèi)存,現(xiàn)在可以明確的告訴你,在Android5.0及以上手動(dòng)調(diào)用System.gc()完全沒(méi)必要,因?yàn)槟阏{(diào)了也完全觸發(fā)不了gc,為什么會(huì)這樣說(shuō)呢?
Talk is cheap,show you the code
我們直接看代碼!
源碼
Android5.0之前的代碼
如下:
/**
* 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();
}
這個(gè)看上去完全沒(méi)問(wèn)題
Android 5.0及以后的代碼
先看System.gc()到底做了什么,如下:
/**
* 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() {
boolean shouldRunGC;
synchronized(lock) {
shouldRunGC = justRanFinalization;
if (shouldRunGC) {
justRanFinalization = false;
} else {
runGC = true;
}
}
if (shouldRunGC) {
Runtime.getRuntime().gc();
}
}
簡(jiǎn)單易懂啊,前面就是一些賦值啊判斷啊,直接看最重要的一句
if (shouldRunGC) {
Runtime.getRuntime().gc();
}
可以看到,只有當(dāng)shouldRunGC為true時(shí),才會(huì)真的去gc,而shouldRunGC的值其實(shí)不就是justRanFinalization的值嗎,那好,我們?nèi)炙阉饕幌拢l(fā)現(xiàn)justRanFinalization出現(xiàn)的地方取值可數(shù),只有兩個(gè)地方:
1、定義的地方
/**
* 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;
2、賦值的地方
/**
* Provides a hint to the VM that it would be useful to attempt
* to perform any outstanding object finalization.
*/
public static void runFinalization() {
boolean shouldRunGC;
synchronized(lock) {
shouldRunGC = runGC;
runGC = false;
}
if (shouldRunGC) {
Runtime.getRuntime().gc();
}
Runtime.getRuntime().runFinalization();
synchronized(lock) {
justRanFinalization = true;
}
}
哇咔咔,so easy,這時(shí)一個(gè)函數(shù)出現(xiàn)在我們眼前runFinalization(),這個(gè)函數(shù)是干嘛的?和System.gc()有什么關(guān)系,直接看函數(shù)的注釋?zhuān)鋵?shí)就是執(zhí)行對(duì)象的finalize()方法,但最關(guān)鍵的是,只有在這個(gè)地方是justRanFinalization的值才會(huì)賦為true,仔細(xì)觀察,還有一個(gè)變量runGC,在System.gc()里會(huì)賦值為true,而在System.runFinalization()里只有runGC為
true時(shí),才會(huì)真的去觸發(fā)gc
總結(jié)
所以說(shuō)只是單純的調(diào)用System.gc(),在Android5.0以上什么也不會(huì)發(fā)生,要么是
- System.gc()和System.runFinalization()同時(shí)調(diào)用
- 直接調(diào)用Runtime.getRuntime().gc()