手机开发经常会遇到内存泄露问题,而且很烦人。这样有个工具查找到泄露的地方就再好不过了。
本文主要简单介绍使用mat工具来定位。
1、出现泄露。
本人开发游戏过程中用到了jbox2d,而每个在释放一个world时,必须调用方法释放里面的body,否则就会产生内存泄露。
我的gaming类中创建了world,并且加入了body。
当我想重建类的时候,我就想先释放该类资源再新建。(释放函数见下面代码,当然,也可以不看。一句话,就是忘了释放world!)
public void gamingGC(){
mySurfaceView = null;
generalBricks.clear();
generalBricks = null;
ht_generalBricks.clear();
ht_generalBricks = null;
ht_generalBricks_x.clear();
ht_generalBricks_x = null;
generalBricksTogold.clear();
generalBricksTogold = null;
bottomButtons.clear();
bottomButtons = null;
}
如此一来,我每次新建的时候,内存就在那一瞬间狂升,然后就挂了。
2 、 使用ddms查看内存情况。
首先打开window ——》 open perspective ——》other —— 》 ddms。
这时会出现ddms界面。假设此时程序已经跑一来。在左上侧的Devices标签栏选择自己要检测的线程。该栏下拉三角,有个update heap. 打开右侧heap标签,点击Cause GC按钮。就可以看到一些内存情况了。注意heap size 和allocated ,如果不动,保持在一个特定范围内,就表示没有内存泄露。
注意,有时候是某些事件触发的,比如说触屏。这时你可以触发这个事件,看内存是不是还能保持稳定。
3、导出hprof文件。
这个很简单,找到上面说的device栏的 dump hprof file 按钮。点击,保存就行了。
4、转换。
我们导出hprof文件时为了能看到里面的内存分配信息。(可以看到是哪个对象!开心吧!) 但是现在导出的hprof文件,还不能直接用mat工具查看,要使用安卓sdk的hprof-conv工具转换。
进入命令行,切换到sdk的tool目录下。(或者配置好环境变量到改目录了也可以不用切换)。
把那个生成的hprof文件放到tool目录下(为了方便),假设是g1.hprof ,输入指令: hprof-conv hp.hprof hpa.hprof
会生成hpa.hprof 文件,我们用的就是这个。
5、下载mat。
http://www.eclipse.org/mat/downloads.php
6、打开MAT,找到可疑泄露的类。
file ——》open heap dump。打开刚才转换好的hprof文件。
选择第二个按钮(直方图)。(create a histogram from .......)。可以按大小排列,看到数值很大的(也就是可疑的),对着它右击——》list object ——》with incoming reference。 是不是你想释放但是还有被引用了?顺着找下去吧。
7、比较两个hprof文件
可能通过上面步骤可以找到内存泄露和位置了。但是我更喜欢一个直观的方法,比较两个hprof文件。
首先,通过断点,在出现问题代码的前后,分别导出hprof文件。
然后,打开histogram以后,找到navigation history 标签。右击里面的histogram,add to Compare Basket。
另外一个hprof也一样。
window ——》compare basket 。打开比较窗口。点击那个红色的感叹号。
此时,看到数值相差很大的,都与jbox2d相关,看来我忘了把jbox2d(world body 等)等释放了。
终于找到了,很开心。真是一个霸气侧漏的工具啊!