您的位置:首页 > 移动开发 > Android开发

Android内存泄露之非静态内部类(handler)、错误静态属性和静态方法

2018-03-04 23:03 316 查看

Android内存泄露之非静态内部类(handler)、错误静态使用

众所周知,内存泄露在 Android 开发中是一个比较严重的问题,系统给每一个应用分配的内存是固定的,一旦发生了内存泄露,就会导致该应用可用内存越来越小,严重时会发生 OOM 导致 Force Close。
    这里所提到的可能导致内存泄露的handler不规范使用,非静态内部类的不规范使用,都是围绕两点:
    1.如何正确的使用静态。
    2.如何正确使用内部类。

一、静态

Android是用Java开发,其静态变量的生命周期遵守Java的设计。我们知道静态变量是在类被load的时候分配内存的,并且存在于方法区。当类被卸载的时候,静态变量被销毁。

1.静态变量在类被加载的时候分配内存。当我们启动一个app的时候,系统会创建一个进程,此进程会加载一个Dalvik VM的实例,然后代码就运行在DVM之上,类的加载和卸载,垃圾回收等事情都由DVM负责。也就是说在进程启动的时候,类被加载,静态变量被分配内存。 

2.静态变量在类被卸载的时候销毁。 类在什么时候被卸载? 在进程结束的时候。所以我们知道,静态变量的生命周期是跟随着整个APP进程的生命周期,若滥用静态则会造成过多占用内存的问题。这种情况可能会发成在工具类中,比如本来想定义一个工具类,里面包含要用到的静态方法,而由于静态方法中需要持有过多的属性,而这些资源也必须是静态的才能被静态方法所持有,甚至会持有context,这就导致无论该方法是否被用到,都会占用大量内存。

二、内部类

我们知道内部类是持有外部类的引用的,当我们的内部类无法被及时释放时,会导致他所引用的外部类也无法被释放,这就造成了内存泄露,这种情况尝放生在handler的使用中。错误用法:@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);

}
};

Message message = Message.obtain();
message.what = 1;
mHandler.sendMessageDelayed(message,10*60*1000);
}

我们看到使用了匿名内部类Handler,而message发送延迟了10分钟,就是说在这个过程中外部类是无法被回收的,造成了内存泄露。解决方案就是使用静态内部类和弱引用,静态内部类不持有外部引用,所以不会造成外部类无法被回收的问题。private NoLeakHandler mHandler;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

mHandler = new NoLeakHandler(this);

Message message = Message.obtain();

mHandler.sendMessageDelayed(message,10*60*1000);
}

private static class NoLeakHandler extends Handler{
private WeakReference<NoLeakActivity> mActivity;

public NoLeakHandler(NoLeakActivity activity){
mActivity = new WeakReference<>(activity);
}

@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
}

当内部类可能会被长期持有的情况下,内部类应该使用静态内部类的方法避免内存泄露。说到这里你可能会产生一个疑问,不是说静态资源的生命周期是跟随着APP进程的生命周期么,当内部类没有被用到的时候不会占用内存么。静态内部类和外部静态属性的生命周期是不同的,静态内部类也要通过new来创建,他的内存分配也是在new的时候创建的,这点需要注意。所以静态内部类是一个比较常见的内存泄露解决方案。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: