内存泄露的原因是引用还存在,无法及时释放内存,android的内存泄露主要是activity销毁不及时。
造成内存泄露主要分为两个原因
- 内部类持有其外部类的引用
- 外部类持有本类引用,而外部类又比本类生命周期长
内部类
内部类主要有
- 静态内部类
- 非静态内部类
因为静态内部类不持有外部类的引用,不会造成泄露。主要讨论非静态内部类。
举个栗子
private void testThread(){
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000 * 60);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
new Runable是个匿名内部类,当activity调用finish()的时候由于线程没有走完,new runable持有activity的引用,所以activity不会被及时的释放内存。
在内部类造成内存泄露的情况下最经典的是handler的原因
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
以前喜欢这样直接在activity new Handler出来,但这样是有风险的,很大可能造成内存泄露。具体原因和解决方法可以看Android中Handler引起的内存泄露
外部类
在activity里面new一个外部类或者调用外部类方法要传进activity引用时,外部类的生命周期要比activity长的话都有可能造成内存泄露,极端的例子是在activity中传进引用获取单例。
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;
}
}
静态变量的生命周期是贯穿整个应用进程的,所以这样在activity获取单例是肯定会造成内存泄露的。