Android内存泄露分析

版权声明:原创作品,转载请注明原创链接地址! https://blog.csdn.net/wangxp423/article/details/81032301

一,内存泄露

内存泄露:一个不在被使用的对象被另一个存活着的对象引用,在这种情况下垃圾回收器会跳过他,因为这种引用关系足以让该对象驻留在内存中,内存泄露是在组织垃圾回收器为未来的内存分配提供空间,这些泄露的对象一直占据着内存,导致我们的堆内存空间变得更小。也加剧了垃圾回收调用的频繁程度,妨碍应用程序的正常执行。

内存溢出:通常的理解就是内存不够,是指堆内存大小超出了应用程序的分配内存范围导致的。通常来讲内存泄漏就是导致内存溢出的罪魁祸首。

二,LeakCanary

leakCanary是一款内存追踪工具,可以帮我们定位到内存泄露,这里不做过多讲述,

LeakCanary中文使用说明

三,Android Profile

android profile可以帮助我们观察内存波动情况

首先我们进入我们的应用,然后能看到内存曲线,一直很平稳,我点手动GC(垃圾箱按钮),使曲线平稳,进入我们要观察的页面,进行操作,发现内存向上波动,然后退出页面,继续点GC,我们发现内存大小并没有回退到之前的波形,而是维持高位,我们基本可以断定当前页面存在内存泄露情况。(如下图)
这里写图片描述

这个时候点击左上角中间按钮”下箭头那个(Dump java heap)”,然后就会生成一个当前内存的一个堆信息。在曲线下面的按个框里面。
这里写图片描述

在这框里面我们可以看到堆内存占用大小。也可以搜索你想看的对象。

三,MAT

相对于android profile,MAT更加直观而且操作更方便。

在上图中的左边框的左上角,有一个导出按钮,Exprot capture to file,点击此按钮,可以导出当前堆信息到一个hprof文件中。

官网MAT下载地址https://www.eclipse.org/mat/
这里写图片描述
下载完成以后双击MemoryAnalyzer.exe,然后点击File–>open file刚才导出的.hprof文件,如果弹出一下错误框
这里写图片描述
说明当前不能识别,我们需要用到android sdk下的hprof-conv.exe进行一下转换
这里写图片描述

打开命令行cd 到当前目录.exe所在目录
这里写图片描述

输入上图红框中的命令,前面的.hprof文件要转换的文件,后面为要转出的文件。文件跟.exe在同一个目录。转换完成以后再用MAT打开。

这里写图片描述

如上图,即为当前导出的.hprof文件的堆信息图。
我们点击下面红框中第一个Histtogram。
这里写图片描述

如上图:

  • Objects:表示该类在内存当中的对象个数。
  • Shallow Heap:这一列中文翻译过来是“浅堆”,表示的是对象自身所占用的内存大小,不包括它所引用的对象的内存大小。
  • Retained Heap:这一列中文翻译过来是“保留堆”,也就是当该对象被垃圾回收器回收之后,会释放的内存大小。其实也就是当前所有对象所占用的内存大小。

在regex输入框可以通过关键字来过滤我们想要找的文件。
这里写图片描述

注:因为我是在点击MyCsdnBlogActivity的时候,产生了大量的内存抖动,并且在GC的时候,内存并没有恢复,所以我们目标就是该activity

右键选中该条目–>list objects–>with incoming references
这里写图片描述

右键条目–>path to gc root–>exclude all phantom/weak/soft etc.references。过滤掉软引用和弱引用
这里写图片描述

然后我们发现在在他的GC节点上有一个ActivityManager下的activitys的引用,至此内存泄露被找到。

四,总结

一般来讲,我们追踪内存泄露,首先使用leak canary基本就可以定位到泄露的位置,如果问题没有解决,这个时候我们就可以使用android profile去追踪内存波动,然后去生成.hprof文件,在用MAT去分析堆信息,从而找到泄露的位置。

后面我会说一下,避免内存泄露的一些注意事项。

文章中有些地方可能说的不够详细,大家也可以参考一下面的文章
https://www.jianshu.com/p/fa016c32360f

Android内存抖动分析与注意事项
Kotlin之Android项目实战

猜你喜欢

转载自blog.csdn.net/wangxp423/article/details/81032301