美文网首页
内存泄漏

内存泄漏

作者: 7570146919ac | 来源:发表于2019-07-08 10:03 被阅读0次

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

  • 内存泄漏:对象被创建之后,没有引用到,当时没有被回收,一直占用着内存
  • 内存溢出:程序使用的空间大于原本系统给它申请的空间

泄漏场景:

单例引起的内存泄漏

单例模式的生命周期常常伴随程序一生,这也就会有内存泄漏出现的间接原因
比如:单例模式中引用的是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忘记解除订阅等。

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

  • Android Lint:Android Studio提供的代码扫描分析工具
  • Leakcanary: Square 公司开源的「Android 和 Java 的内存泄漏检测库」

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

相关文章

网友评论

      本文标题:内存泄漏

      本文链接:https://www.haomeiwen.com/subject/nnmnhctx.html