内存泄漏
首先先知道什么是内存泄漏
一般情况下,就是说A持有B的引用,当B需要回收但A不需要的时候,A没有释放这个B的引用,那么B就是可达的,就不会被回收,造成内存泄漏
如何知道是否发生了内存泄漏呢
Android中常见内存泄漏
- 静态引用引用了该释放的对象
- 非静态内部类
- Webview
- 资源未释放
使用android studio的profile进行内存泄漏
实际操作
- 里面有个拖动时间轴查看内存分配情况的操作,但是前提是,你链接的设备的系统是8.0或者以上的
通过多次开关页面,观察内存的波动,感觉total内存变化太大,貌似不太符合实际情况,所以进行Java部分的内存大小观察,发现Java部分的应该是反映了内存情况的。
比如我们要观察A页面是否发生了内存泄漏,或者你怀疑A页面发生了内存泄漏的话,可以在打开A页面之前,观察记录此时的内存的使用情况
然后打开A页面进行操作,操作结束后,进行GC,,GC后再观察此时的total和Java的内存使用情况,来判断你的页面是否发生了内存泄漏
点击dump java heap图表,会对当前内存进行分析
选择按包名排列,找到我们自己的包名,看里面的对象,比如此时存在A页面中的对象,说明这个对象实例还存在,我们点击它会在右边出现instance窗口,我们点击里面的实例,会在下面出现引用窗口。我们右键引用,会出现两个选项,可以帮助我们定位到代码
在 Instance View 窗格中,点击一个实例。此时下方将出现 References 标签,显示对该对象的每个引用。
或者,点击实例名称旁边的箭头以查看其所有字段,然后点击一个字段名称以查看其所有引用。如果您要查看某个字段的实例详细信息,请右键点击该字段并选择 Go to Instance。
在 References 标签中,如果您发现某个引用可能在泄漏内存,请右键点击它并选择 Go to Instance。这样会从堆转储中选择相应的实例,从而向您显示它自己的实例数据。
展开引用的箭头,查看下面有没有那个引用是在自己项目的文件中,去查看,比如
就查看 in 后面的,有没有哪个是自己的页面或者文件名称
tips
认为还有一种做法,就是比如进行一次操作会产生一个对象,如果这个对象是内存泄漏的话,我们进行重复操作,那么就会产生多个对象。我们就可以根据实例的个数来判断它是否发生了泄漏,比如我连续操作了三次,发现
我们确定了这个对象发生了内存泄漏,然后就是要找到它的引用,确定是哪个引用导致的内存泄漏。处理这个引用
其他工具
mat
这个文章中,提到使用hprof-conv指令,这个是sdk下的工具,在platform-tools目录下,所以我们需要进入这个目录下,才能使用这个指令。
但这个mat还是基于as的profile生成的内存情况的文件进行分析的
Leaks
- 我们可以使用Leaks来进行内存泄漏检测,关于Leaks的使用可以先参考博文
- 参考博文
我们操作App,在发生泄漏的时候,Leaks会进行记录,我们可以查看记录来排查内存泄漏
看下官方的举例的图:
- 最顶部的是一个GC root
- 最底部发生泄漏的对象
这整个图可以看到GC root是如何到达泄漏的对象的,也就是可达性的过程