內(nèi)存泄露的原因是引用還存在身辨,無(wú)法及時(shí)釋放內(nèi)存睛琳,android的內(nèi)存泄露主要是activity銷(xiāo)毀不及時(shí)淆两。
造成內(nèi)存泄露主要分為兩個(gè)原因
- 內(nèi)部類(lèi)持有其外部類(lèi)的引用
- 外部類(lèi)持有本類(lèi)引用,而外部類(lèi)又比本類(lèi)生命周期長(zhǎng)
內(nèi)部類(lèi)
內(nèi)部類(lèi)主要有
- 靜態(tài)內(nèi)部類(lèi)
- 非靜態(tài)內(nèi)部類(lèi)
因?yàn)殪o態(tài)內(nèi)部類(lèi)不持有外部類(lèi)的引用默终,不會(huì)造成泄露。主要討論非靜態(tài)內(nèi)部類(lèi)犁罩。
舉個(gè)栗子
private void testThread(){
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000 * 60);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
new Runable是個(gè)匿名內(nèi)部類(lèi)齐蔽,當(dāng)activity調(diào)用finish()的時(shí)候由于線(xiàn)程沒(méi)有走完,new runable持有activity的引用床估,所以activity不會(huì)被及時(shí)的釋放內(nèi)存含滴。
在內(nèi)部類(lèi)造成內(nèi)存泄露的情況下最經(jīng)典的是handler的原因
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
以前喜歡這樣直接在activity new Handler出來(lái),但這樣是有風(fēng)險(xiǎn)的丐巫,很大可能造成內(nèi)存泄露蛙吏。具體原因和解決方法可以看Android中Handler引起的內(nèi)存泄露
外部類(lèi)
在activity里面new一個(gè)外部類(lèi)或者調(diào)用外部類(lèi)方法要傳進(jìn)activity引用時(shí),外部類(lèi)的生命周期要比activity長(zhǎng)的話(huà)都有可能造成內(nèi)存泄露鞋吉,極端的例子是在activity中傳進(jìn)引用獲取單例鸦做。
public class Singleton {
private static Singleton instance;
private Context mContext;
private Singleton(Context mContext){
this.mContext = mContext;
}
public static synchronized Singleton getInstance(Context mContext) {
if (instance != null){
instance = new Singleton(mContext);
}
return instance;
}
}
靜態(tài)變量的生命周期是貫穿整個(gè)應(yīng)用進(jìn)程的,所以這樣在activity獲取單例是肯定會(huì)造成內(nèi)存泄露的谓着。