x

Handler内存泄漏原理和避免

内存泄漏原理

在一般情况下,我们创建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 referenceQueue = new ReferenceQueue<>();

Object o = new Object();

SoftReference softO = new SoftReference<>(o, referenceQueue);

o = null;

弱引用:比软引用更弱一点。对于GC而言,无论内存是否足够,只要 JVM 开始进行垃圾回收,那些被弱引用关联的对象都会被回收。使用的时候一般和引用队列一起用。

ReferenceQueue referenceQueue = new ReferenceQueue<>();

Object o = new Object();

WeakReference weakO = new WeakReference<>(o, referenceQueue);

o = null;

虚引用:最弱的引用,你无法获取引用的对象(就是get()只会返回null),相当于没有引用。使用的时候必须和引用队列一起用。主要是感知对象被和系统回收的时机以采取对应的行动。

ReferenceQueue referenceQueue = new ReferenceQueue<>();

Object o = new Object();

PhantomReference phantomO = new PhantomReference<>(o, referenceQueue);

o = null;

参考材料

Java四种引用类型 - CNBlog https://www.cnblogs.com/liyutian/p/9690974.html

Copyright © 2088 杭州玩家联盟 - 区域游戏活动聚合平台 All Rights Reserved.
友情链接
Go To Top