說的Android的內(nèi)存泄漏什湘,大家都會(huì)想到由全局static變量強(qiáng)引用當(dāng)前對(duì)象(e.g. activity)埠通,導(dǎo)致當(dāng)前對(duì)象生命周期結(jié)束的時(shí)候赎离,無法被gc回收,從而造成內(nèi)存泄漏。首先這個(gè)觀點(diǎn)是沒有問題的. 但是有人說這樣端辱,如果這個(gè)對(duì)象被頻繁創(chuàng)建銷毀梁剔,那么就會(huì)有多個(gè)對(duì)象無法被回收,泄漏.? 真實(shí)情況是這樣的嗎舞蔽。?
static變量是全局變量憾朴,存放在方法區(qū),是全局唯一的喷鸽。 在對(duì)象重新創(chuàng)建的時(shí)候众雷,該變量會(huì)重新賦值,那么其之前所引用的對(duì)象做祝。就沒有被gc roots引用砾省,理論上,是可以被gc回收的混槐,就是說编兄,如果在gc回收的情況下,最多只有一個(gè)對(duì)象被泄漏.? 真實(shí)情況是不是這樣呢声登。
下面我們通過一個(gè)簡(jiǎn)單的例子來看一下狠鸳。
public class MainActivityextends AppCompatActivity {
????private static final String TAG ="MainActivity";
????private static ContextmContext;
????ClassDemodemo =new ClassDemo();
? ?@Override
? ? protected void onCreate(Bundle savedInstanceState) {
????????????super.onCreate(savedInstanceState);
????????????setContentView(R.layout.activity_main);
????????????Log.d(TAG,"onCreate: ");
????????????mContext =this;
}
protected? void onDestroy(){
????????super.onDestroy();
????????Log.d(TAG,"onDestroy: ");
????}
}
public class ClassDemo {
private static final String TAG ="ClassDemo";
????public int[]arr =new int[10000];
????public ClassDemo(){
????????Log.d(TAG,"ClassDemo: ");
????}
}
使用AndroidStudio編譯安裝到手機(jī)上,并運(yùn)行悯嗓,然后點(diǎn)擊AndroidStudio->Run->Profile‘a(chǎn)pp’件舵,獲取當(dāng)前java heap信息. 關(guān)于Profile的用法,請(qǐng)參考
https://blog.csdn.net/yangjie5250/article/details/80264517?(因?yàn)檫@個(gè)當(dāng)時(shí)沒有截圖脯厨,懶得重新運(yùn)行了铅祸,所以請(qǐng)參考其他文章)
直接運(yùn)行,打開app,這個(gè)時(shí)候執(zhí)行dump heap临梗,我們看結(jié)果涡扼。 只有一個(gè)MainActivity對(duì)象。? 注意左上角的選項(xiàng)盟庞。
Arrange by package. 這樣方便看一些吃沪。
然后按back鍵返回,再打開什猖,再返回巷波,重復(fù)多次。然后在重復(fù)上面的步驟卸伞,將heap 的情況dump出來抹镊。此時(shí)我們看到,此時(shí)有多個(gè)對(duì)象存在
另外你也可以看圖中的用圈圈住的那一列荤傲,那一列顯示對(duì)象個(gè)數(shù)垮耳。
從結(jié)果看,的確存在多個(gè)對(duì)象.? 那么是不是的確存在多個(gè)對(duì)象泄漏呢遂黍。 我們繼續(xù)操作
這次我們執(zhí)行 dump heap之前终佛,先強(qiáng)制執(zhí)行下GC ,點(diǎn)擊下圖中的 垃圾簍。 然后再執(zhí)行dump heap (點(diǎn)擊向下箭頭)雾家。再來看heap的情況
我們發(fā)現(xiàn)只剩下一個(gè)MainActivity了铃彰。 說明了什么. 說明了其他的對(duì)象,是可以gc 掉的芯咧,真正泄漏的只有一個(gè)對(duì)象牙捉。
總結(jié):
由全局靜態(tài)變量強(qiáng)引用當(dāng)前對(duì)象引起的內(nèi)存泄漏,不會(huì)因?yàn)椴粩嗟闹亟ㄤN毀對(duì)象而泄漏多個(gè)對(duì)象敬飒。最終只有一個(gè)被正在引用的對(duì)象泄漏邪铲,其他的對(duì)象都可以被gc回收掉. 至于同時(shí)存在多個(gè)對(duì)象的情況,是因?yàn)檫@個(gè)時(shí)候无拗,還沒有g(shù)c發(fā)生.