一、知识介绍
1.1 为什么要抓取hprof
hprof文件中记录了当前进程内存的使用情况,对于一些难以解决的OOM问题,提取出对应进程的hprof文件可以很好的分析这种问题。
分析hprof的工具
Java Heap Analyzes Tool
Eclipse Memory Analyzer
1.2 生成hprof指令
adb shell am dumpheap pid/pkgName file
进入adb 之后,可以不用前面的adb shell,直接使用am dumpheap pkgName file,这个file是文件存储的完整路径加上文件名.
1.3 得到pid
adb shell ps -e | grep pkgName
加入pkgName是 com.android.systemui,生成结果如下:
pid过滤指令.png
这些item分别代表什么意思了?
ps指令item.png
USER:进程当前的用户
PID:当前进程ID
PPID:当前进程父进程ID
VSZ:进程的虚拟内存大小,单位KB
RSS:进程实际占用内存大小,单位KB
WCHAN:进程正在sleep的内核函数名,根据/root/sysytem.map
ADDR:进程地址空间
S:进程状态
NAME:当前进程的名称
我们这里关注的是PID,根据这个描述,那么《pid过滤指令》图中的PID是 1918,这个PID是生成hprof的重要参数。
1.4 生成指定pid的hprof
am dumpheap pid /data/local/tmp/fileName.hprof
上面的pid就是进程id,其实在O版本上也可以直接用processName代替的,例如要获取com.android.systemui的hprof信息,可以写成如下:
am dump com.android.systemui /data/local/tmp/fileName.hprof
二、抓取hprof文件的方法
2.1 在当前进程中抓取当前进程的hprof信息
这个正常的app就可以做这样的工作,因为在当前进程dump当前进程的信息,这是没有什么权限问题的,关键的接口就是 android.os.Debug.java
Debug.java
public final class Debug
{
public static void dumpHprofData(String fileName) throws IOException {
VMDebug.dumpHprofData(fileName);
}
public static void dumpHprofData(String fileName, FileDescriptor fd)
throws IOException {
VMDebug.dumpHprofData(fileName, fd);
}
public static void dumpHprofDataDdms() {
VMDebug.dumpHprofDataDdms();
}
public static native void dumpNativeHeap(FileDescriptor fd);