OOM的解决之道

来源:互联网 发布:洛氏霍克指标源码 编辑:程序博客网 时间:2024/05/01 16:25

Out of memory的出现:
这种OutOfMemoryError需要抓取死之前的此进程的hprof才能解决,以下提供两种方法抓取hprof文件

一、手动抓取(发现对应进程的DVM heap很大(超过100M)时,手动抓取其当时的hprof):

具体查看当前进程占用dvm heap的大小的方法:
1. 输入adb shell dumpsys meminfo PIDXXX>meminfo.txt中有dalvik heap 大小。
2. 可以通过DDMS,选中对应进程。直接观察。

具体抓取方式:
通过命令方式抓取方法:
1. 通过adb输入如下命令,PIDXXX为对应进程的PID:
adb remount
adb shell chmod 0777 /data/misc
adb shell kill -10 PIDXXX
2. 会在/data/misc目录下生成一个命名以pidXXX.hprof结尾的hprof文件。
3. 然后通过adb pull将这个文件弄出来发过来,还请通过创建时间确认是这次生成的。

直接连上DDMS抓取:
1. 在device窗口选中对应进程,点击Update Heap图标(绿色圆柱体)。
2. window =>Show View =>heap,在此窗口中查看对应进程的heap大小。
3. 当发现一直在增长且很大时,点击device窗口的Dump Hprof file 图标(绿色圆柱体,右边一条红线)
4. 等几秒中会弹出保存hporf的路径,然后就可以抓取到当时的hprof了。

二、如果概率很小没有固定复现步骤(比如monkey test这种),随后会给贵司申请一个patch,
patch的目的是在出现out of memory的时候主动将hprof抓取到db中,
这种方法需要在开机后设置:
adb shell setprop dalvik.vm.oome-hprof-path /data/anr
adb shell chmod 0777
adb stop
adb start
拔掉电池重启(Linux重启)后,属性将不起作用,这个patch也不起作用了,就需要重新设置属性再重启android上层。

另外:android4.4版本上可以自动抓取hprof,按如下步骤复现问题就能抓到hprof文件!

1. 连上adb执行如下命令(会自动重启,把电池开机后属性会无效,需要重新输入):
adb shell setprop dalvik.vm.oome-hprof-path /data/anr
adb shell chmod 0777 /data/anr/
adb shell stop
adb shell start
2. 开完机后清除mtklog文件夹,再开启mobilelog.
3. 然后复制问题,出现问题后等几分分钟,然后将mtklog发过来。

 

三、如何用MAT来分析,前提是Android开发和测试的工具安装完整,SDK,Eclipse:
1.打开Eclipse
2.选择 Help->Install New Software;
3.在Work with中添加站点:http://download.eclipse.org/mat/1.0/update-site/(这个地址可能会变化,但是新的地址可以在官方网站上找到:http://www.eclipse.org/mat/downloads.php )
4.生成.hprof文件:插入SD卡(Android机器很多程序都需要插入SD卡),并将设备连接到PC,在Eclipse中的DDMS中选择要测试的进程,然后点击Update Heap 和Dump HPROF file两个Button。
.hprof 文件会自动保存在SD卡上,把 .hprof 文件拷贝到PC上的\ android-sdk-windows\tools目录下。这个由DDMS生成的文件不能直接在MAT打开,需要转换。
运行cmd打开命令行,cd到\ android-sdk-windows\tools所在目录,并输入命令hprof-conv xxxxx.hprof yyyyy.hprof,其中xxxxx.hprof为原始文件,yyyyy.hprof为转换过后的文件。转换过后的文件自动放在android-sdk-windows\tools 目录下。
OK,到此为止,.hprof文件处理完毕,可以用来分析内存泄露情况了。
5.打开MAT:
在Eclipse中点击Windows->Open Perspective->Other->Memory Analysis
6.导入.hprof文件
在MAT中点击 File->Open File,浏览到刚刚转换而得到的.hprof文件,并Cancel掉自动生成报告,点击Dominator Tree,并按Package分组,选择自己所定义的Package 类点右键,在弹出菜单中选择List objects->With incoming references。
这时会列出所有可疑类,右键点击某一项,并选择Path to GC Roots->exclude weak/soft references,会进一步筛选出跟程序相关的所有有内存泄露的类。据此,可以追踪到代码中的某一个产生泄露的类。


 

0 0
原创粉丝点击