HPROF Viewer and Analyzer

Posted by JackPeng on June 29, 2016

翻译自https://developer.android.com/studio/profile/am-hprof.html

HPROF Viewer and Analyzer

使用Android Monitor提供的Memory Monitor观察内存使用情况的同时,也可以把Java Heap导出为一个Android规格的HPROF格式文件的快照。HPROF Viewer可以显示java heap中每个class的实例,以及他们的reference tree,来帮助你跟踪内存使用情况和查找内存泄露,HPROF是一个J2SE中Heap的二进制格式。

为什么要观察Java Heap?

通过Java Heap可以知道:

  • 可以按类型显示对象申请的内存大小;
  • 可以观察自动或手动触发的GC事件;
  • 可以定位可能存在内存泄露的对象;
  • 但是,你需要一直盯着memory monitor中heap变化的图表。

    HPROF Analyzer 可以发现以下潜在的问题:

    所有已经被destroy但是仍然可以被GC root访问到的activity实例;

    重复的string对象;

    一个reference tree的顶级引用者,如果能把它移除,则他直接或间接引用的对象都可以被GC回收掉,这是一个释放内存的方法。

    看懂HPROF Viewer

    HPROF Viewer打开Hprof后如下图:

    image

    可以显示如下信息:

    Column Description
    Class Name The Java class responsible for the memory.
    Total Count Total number of instances outstanding.
    Heap Count Number of instances in the selected heap.
    Sizeof Size of the instances (currently, 0 if the size is variable).
    Shallow Size Total size of all instances in this heap.
    Retained Size Size of memory that all instances of this class is dominating.
    Instance A specific instance of the class.
    Reference Tree References that point to the selected instance, as well as references pointing to the references.
    Depth The shortest number of hops from any GC root to the selected instance.
    Shallow Size Size of this instance.
    Dominating Size Size of memory that this instance is dominating.

    打开右侧的 Analyzer Tasks窗口,有两个可以执行的task,查找内存泄露和查找重复string。

    其中reference tree视图中,可以看到LeakActivity被多个对象引用,格式为:变量名 in 类名;

    比如:this$0 in com.example.dunno.myapplication.LeakActivity$1,表示LeakActivity中有个$1类引用了LeakActivity,LeakActivity在该类中的名字是this$0;同时,LeakActivity中的$1类又被Message中的target和LeakActivity的myLeakHandler同时引用。

    同级item之间是并列关系,表示引用了同一父级的类名部分的对象,也就是父级部分的类名部分对应子级的变量名,是同一个对象,一个表类型,一个表名称。把外层叫做父级,内层叫做子级,则子级引用了父级对象,每个父级可以有多个子级。

    打开右侧的 Analyzer Tasks窗口,有两个可以执行的task,查找内存泄露和查找重复string。执行Detect Leaked Activities后,在Analysis Results窗口检测到泄露的Activity,有2个同类型的Activity对象,表示该对象泄露了,无法回收。