Handler 内存泄漏问题



Handler
非静态内部类会持有外部类的一个隐式引用
Handler 对象会因为被MessageQueue持有引用 不能被
GC回收, handler 对象有持有 Activity的一个隐士引用
所以Activity也不能被回收 Context就不能被回收
当MessageQueue中的消息处理完之后才有可能会被回收

解决:
将Handler设置为静态类,静态类内部类(不会持有外部类的隐士引用)
如果需要使用 Activity 就使用 SoftReference 的方式持有

    private static class MainHandler extends Handler {

        private SoftReference activity = null;

        MainHandler(MainHomeActivity activity) {
            this.activity = new SoftReference<>(activity);
        }

        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_GET_CLEANERS:
                    DebugLog.i("获取所有设备列表成功");
                    break;
                case MSG_NET_ERROR:
                    DebugLog.i("网络请求失败");
                    break;
                default:
                    break;
            }
        }
    }

    private MainHandler mHandler = new MainHandler(this);


1.强引用 Strong Reference
2.软引用  Soft Reference
3.弱引用  Weak Reference
4.虚引用   Phantom Reference


强引用:

a.如果一个对象具有强引用,那垃圾回收器绝不会回收它,内存不足时,宁抛异常OOM,程序终止也不回收;

--------------------------

软引用:

JDK提供创建软引用的类SoftReference 

a.特点就是:如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它;
如果内存不足的话就会在oom之前回收这个对象,
 B 只要垃圾回收器没有回收它,该对象就可以被程序使用,软引用可用来实现内存敏感的高速缓存;
d. 软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。
垃圾回收线程会在oom之前来回收不经常用的软引用对象,对于新的软引用不回收,
在回收这些对象之前,我们可以通过get方法,Object anotherRef=(Object)aSoftRef.get(),重新获得对该实例的强引用。回收之后,调用get()方法就只能得到null了。

--------------------------

弱引用:

弱引用与软引用的区别:只具有弱引用的对象拥有更短暂的生命周期。
特点: 

A 生命周期比较短
B 垃圾回收线程扫描到弱引用就会回收
C 但是垃圾回收线程的优先级比较低,一般不宜发现弱引用
D 弱引用也和引用队列联合使用

--------------------
虚引用 :

一般不使用


Lrucache    里面是用的是 LinkedHashMap  使用的是强引用

Lrucache 最近最少使用的数据排在队尾

当数据缓存满的时候

还要往里面添加数据的时候 

会把排在后面的数据从队列中移除

腾出空间给图片使用












你可能感兴趣的:(Handler 内存泄漏问题)