内存泄漏原理
在一般情况下,我们创建Handler的时候,都是这么创建的。
贴一个百度翻译:这个Handler类应该是静态的,否则可能会发生泄漏。
就是说如果不将其设置成静态的,就会发生内存泄漏。
那么发生内存泄漏的原理是:内部非静态类会隐式的持有外部类的引用。
举一个例子:我在一个空Activity的onCreate()方法中这么写。
//在Java中,非静态内部类,可以隐性的拥有外部类的引用
Handler handler = new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
Log.i(TAG, "handleMessage: " + this);
//即使在Handler内部,我也能操作MainActivity的内容
Log.i(TAG, "handleMessage: " + MainActivity.this);
}
};
new Thread(new Runnable() {
@Override
public void run() {
handler.sendEmptyMessage(1);
}
}).start();
运行之后结果如下:
在这个例子中,new Handler后面花括号的就是我们的非静态匿名内部类,也是一个非静态内部类。然后在这个内部类中,我一样可以访问Activity的一切内容(比如说toString)。
Handler中对Activity的引用是强引用,强引用不会被GC回收。
然后在Activity执行onDestroy()后本来准备被系统回收,却因为内部还有一个Handler一直指向它,而导致Activity无法被回收,这就是内存泄漏了。
避免
- 使用弱引用来运行Handler,这样在不需要的时候,不用我们自己动手,系统就会自行的回收分配给Handler的内存,已经其中伴随着的其他外部类。
- 使用静态变量,使用静态变量之后,就无法持有外部类的引用了。
引用与GC回收机制简单介绍
GC,也就是Garbage Collection,垃圾回收机制。对于一个对象而言,如果在某一时间没有任何一个引用指向它,他就将会被回收所分配的内存。
然后是引用类型。简单来说,Java是存在引用类型的。而这个引用类型就类似于C语言的指针一样的东西。
-
强引用:我们平时的各种声明语句就是强引用。对于GC而言,它无论如何都不会回收被强引用的对象。哪怕你哪天内存不够了,它就是给你报一个out of memory也不会回收
Object o = new Object(); String s;
在这种情况下,如果想要回收这个Object()所分配的内存,那就只要o = null。这样如果没有任何引用指向这个实例,他就会在某一个时间被回收掉。
-
软引用:比强引用稍微弱一点。对于GC而言,哪天如果内存不足了,他就会强制回收软引用的对象的内存。回收后还不够才会报out of memory。使用的时候一般和引用队列一起用。
ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>(); Object o = new Object(); SoftReference<Object> softO = new SoftReference<>(o, referenceQueue); o = null;
-
弱引用:比软引用更弱一点。对于GC而言,无论内存是否足够,只要 JVM 开始进行垃圾回收,那些被弱引用关联的对象都会被回收。使用的时候一般和引用队列一起用。
ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>(); Object o = new Object(); WeakReference<Object> weakO = new WeakReference<>(o, referenceQueue); o = null;
-
虚引用:最弱的引用,你无法获取引用的对象(就是get()只会返回null),相当于没有引用。使用的时候必须和引用队列一起用。主要是感知对象被和系统回收的时机以采取对应的行动。
ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>(); Object o = new Object(); PhantomReference<Object> phantomO = new PhantomReference<>(o, referenceQueue); o = null;
参考材料
Java四种引用类型 - CNBlog
https://www.cnblogs.com/liyutian/p/9690974.html