内存泄漏:应用/JVM使用资源之后没有及时释放,导致应用内存中持有了不需要的资源,这是一种状态描述。android中常见的常见有下面几种
- Activity对象未被回收
- 容器造成
1.Activity对象未被回收
1.1静态变量引用Activity对象
通过静态变量引用
activity对象时,会导致Activity对象所占有的内存不被回收,造成内存泄漏。因为静态变量存在与JVM的方法区,本身就是GC ROOT,一般不会被GC掉。
/**
* Created by HuaChao on 2016/8/13.
*/
public class Util {
private static Activity sActivity;
public static void setActivity(Activity activity) {
sActivity = activity;
}
public static void startActivity(Class nextActivity) {
Intent intent = new Intent(sActivity, nextActivity);
sActivity.startActivity(intent);
}
}
一旦activity destroy后,由于这个activity还在被Util.java中的静态变量持有,所以不会被回收,导致内存泄漏
1.2(匿名)内部类
在java基础中,我们得知,非静态的(匿名)内部类持有外部类的一个引用,如果我们在外部类定义了一个静态变量,而这个静态变量指向内部类对象。那么最终会导致整个外部类对象不会被回收,造成内存泄漏
影响链:外部类的静态变量指向内部类对象,内部类对象持有外部类引用,回收外部类对象时由于静态变量的存在,导致引用链还存在,所以不会被回收。
1.3 Handler
如果我们在Activity中定义了Handler对象,那么Handler肯定会持有Activity的引用。而Message对象是持有Handler引用的(target属性就是Handler),这样就会导致Message间接持有了Activity,如果在activity destroy后消息队列中还有message对象的话,此时activity是不会被回收的。(所以我们可以在onDestroy中removeMessage来避免?)
这种情况下的解决办法是不让handler持有activity的引用,怎么做?用静态内部类就可以!静态内部类不会持有外部类的引用,完美!!!
2.集合对象造成的泄漏
静态变量所引用的对象是不会被回收掉的。而我的静态集合类中,包含有大量的对象,这些对象不会被回收。另外,如果集合中保存的对象又引用到了其他的大对象,如超长字符串、Bitmap、大数组等,很容易造成OOM。
3.资源对象没有关闭造成内存泄漏
当我们打开资源时,一般都会使用缓存。比如读写文件资源、打开数据库资源、使用Bitmap资源等等。当我们不再使用时,应该关闭它们,使得缓存内存区域及时回收。虽然有些对象,如果我们不去关闭,它自己在finalize()函数中会自行关闭。但是这得等到GC回收时才关闭,这样会导致缓存驻留一段时间。如果我们频繁的打开资源,内存泄漏带来的影响就比较明显了。
基本转载自这篇