Android OOM 问题

一.引言
Android系统对dalvik的vm heapsize是有硬性限制的,当java进程申请空间超过MAX值的时候,就会抛出OOM异常,可以通过如下命令,查看这个MAX值。
adb shell getprop | grep dalvik.vm.heapgrowthlimit

二.详述
1. 一般出现OOM的时候,在Log中是能够很明显看出来的,这里注意oom是一个error而非异常哟!
诸如信息:
Casued by:java.lang.OutOfMemoryError:Failed to allocate …… until OOM
…….
…….

Log中的信息只是打印了出现oom的当时那一次的backtrace,并不代表是这个backtrace引起的内存泄漏,因为在这之前进程就已经超过了MAX值。log只能看到这里,深入分析就需要用工具了,最常用的当然是mat工具了(Memory Analyzer)。

下载地址是:http://www.eclipse.org/mat/

2.常用的分析手段
A.使用下面的命令抓取对应进程的hprof文件:
adb shell am dumpheap com.android.test /sdcard/temp.hprof

B.抓取复现时候某一次的该进程的内存占用情况:
adb shell dumpsys meminfo com.android.test > meminfo.txt

C.hprof文件需要转换成mat工具可以识别的文件:
使用SDK的工具hprof-conv.exe可以将dumpheap转换成mat工具可识别的文件
hprof-conv D:\temp.hprof D:\temp_conv.hprof

D.使用mat工具
这个网上实在太多了,大致写下一般用到的:
a.先用mat打开转换过的hprof文件;
b.查看饼状图就可以看到哪个对象被频繁调用了;
c.Dominator tree界面可以搜索任意当前存在对象;
d.选择某个Object对象,点击右键,选择“List object | with outgoing references”,可以查看任意成员变量值;
e.点击“path to GC Roots”可以查看类的引用;

3.常见的原因
a.binder内存耗尽,异步binder/同步binder;
b.资源比较常见的是图片bitmap,未及时的释放,导致内存堆积;
c.注册监听者,但是没有remove导致了JNI 弱引用爆表;

猜你喜欢

转载自blog.csdn.net/zplxl99/article/details/79548007