美文网首页Android面试随笔
Android内存泄漏分析

Android内存泄漏分析

作者: 大鹏5004 | 来源:发表于2019-06-17 10:43 被阅读0次

    内存泄漏的原因:生命周期不一致,导致无用的对象不能被回收。

    一、首先要一下说明内存泄漏和内存溢出的区别:

        内存泄漏:Memory Leak , 无用的对象应该被回收的没有被回收。

        内存溢出:常说的OOM,系统没有足够的内存供分配了。

    少量的内存泄露无碍,但如果不断的累积的话,超过系统上限值,最终就会导致内存溢出。

    检测工具:

        Mat工具

        LeakCanary:原理 watch一个将要销毁的对象

    内存 

    栈  基本数据类型  对象的引用

    堆 new出来的类型  gc管理  所有线程共享

    方法区  静态区  所有class对象 静态变量  所有线程共享

    导致内存泄漏的原因:

    1、单例引发的内存泄漏(传入conext)————传入全局的ApplicationContext。

    2、非静态内部类创建静态实例造成内存泄漏  ————内部类改为静态内部类(非静态内部类会隐性地持有外部类的引用,而静态内部类则不会)。

    3、Handler造成内存泄漏(生命周期与Activity不一致)————1、将Handler声明成静态的 2、通过弱引用的方式引入Activity。

    4、线程造成的内存泄漏(匿名的AsyncTask/Runnable/Thread对象 持有外部类的引用,导致外部类不能被回收)————内部类声明为静态内部类,不持有外部类的引用

    5、WebView造成的内存泄漏 (解析网页时申请堆内存用来保存页面元素)————1、将WebView所处的Activity放在一个单独的进程中,2、检测到应用占用内存过多的时候调用Process.killProcess(Process.myPid())方法。

    Leakcanary原理:

    1、Activity Destroy之后将它放在一个WeakReference

    2、这个WeakReference 关联到一个ReferenceQueue

    3、查看ReferenceQueue是否存在Activity的引用

    4、如果该Activity泄漏了,Dump出heap信息,然后分析泄漏路径。

    四种引用类型

    1、强引用(StrongReference)正常使用的对象,gc垃圾回收器不会回收强引用(宁愿OOM也不回收)

    2、软引用 (SoftReference)  内存足够时不会被回收,内存不足时被回收,可以结合引用队列使用

    3、弱引用 (WeakReference)  生命周期更短,gc回收的时候不管内存是否够用都会被回收,可以结合引用队列使用

    4、虚引用  垃圾回收器在任何时候都可以回收虚引用

    ReferenceQueue: 软引用/弱引用  对象被垃圾回收,Java虚拟机会把这个引用加入到与之关联的引用队列中。

    LeakCanary分析内存泄漏流程

    1、首先会创建一个refwatcher,启动一个ActivityRefWatcher

    2、通过ActivityLifecycleCallbacks把Activity的onDestory生命周期与ActivityRefWatcher关联

    3、最后在线程池中去开始分析内存泄漏

    总结checkForLeak

    1、把.hprof转为Snapshot(内存快照)

    2、优化gcroots

    3、找出内存泄漏的对象/找出泄漏对象的最短路径

    总结findLeakingReference (找到内存泄漏对象)

    1、在snapshot快照中找到第一个弱引用

    2、遍历这个对象的所有实例

    3、如果key值和最开始定义封装的key值相同,那么返回这个泄漏对象

    总结findLeakTrace方法 (找到最短泄漏路径)

    1、解析hprof文件,把这个文件封装成snapshot

    2、根据弱引用和前面定义的key值,确定泄漏的对象

    3、找到最短泄漏路径,作为结果反馈出来。

    相关文章

      网友评论

        本文标题:Android内存泄漏分析

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