内存泄漏

2019-07-08  本文已影响0人  7570146919ac

内存泄漏和内存溢出的区别

泄漏场景:

单例引起的内存泄漏

单例模式的生命周期常常伴随程序一生,这也就会有内存泄漏出现的间接原因
比如:单例模式中引用的是Activity的context,而单例的生命周期比Activity的要长,所以当单例引用activity的实例时,activity被销毁,而activity无法被回收,这就造成内存泄漏,eg:

public class Single{
    private static Single instance;
    private Context mContext;

    public Single(Context context) {
        mContext = context;
    }

    public static Single getInstance(Context context){
        if (instance == null){
            instance = new Single(context);
        }
        return instance;
    }
}

如上面例子,如果单例持有application的context就不会造成内存泄漏,引用application的生命周期和单例一样长

匿名内部内以及非静态内部类

特点:匿名类和非静态内部类都持有外部类的引用

匿名内部类---Handle

匿名内部类造成内存泄漏比较经典的场景就是Handle,当Handle的消息还没有发送完,activity就被销毁了,这时候的activity是无法被回收的
eg:


handle问题.png

如何解决Handler泄漏呢?我们用static修饰Handler,这样Hanlder的生命周期就与Activity无关了。如果想引用Activity实例,这里可以用一个弱引用来获取。或者可以在Activity 的onDestroy() 方法中移除所有的消息


handle解决.png

Thread泄漏

在Activity中new Thread时,如果在子线程做耗时操作,当Activity被销毁后,子线程的工作并未完成,此时会内存泄漏。


threa.png

这里可以使用继承Thread实现静态内部类来解决

Stream未关闭

在调用了流之后,一定要记得关闭流。用到流的地方一般都是文件操作,虚拟机无法通过垃圾回收来释放这些资源。

其他泄漏

例如service忘记解除绑定,broadcastReceiver忘记解除订阅,EventBus忘记解除订阅等。

常用的检测内存泄漏的工具

总结:很大程度上引起内存泄漏的原因还是在于对象没有及时被回收

上一篇 下一篇

猜你喜欢

热点阅读