第48讲 Perfetto 内存分析之分析Java Heap

本讲是Android Camera性能分析专题的第48讲,我们介绍Perfetto内存分析之使用Perfetto来分析Java Heap。

更多资源:

资源 描述
在线课程 极客笔记在线课程
知识星球 星球名称:深入浅出Android Camera
星球ID: 17296815
Wechat 极客笔记圈

如何查看某个进程的Java Heap用量

对App开发者而言,可以使用Android Studio的Profiler功能。但最快捷的方式还是使用dumpsys,可以执行:

dumpsys meminfo [pid/pkg]

举例:dumpsys meminfo org.codeaurora.snapcam 输出如下:

如何查看某个进程的Java Heap用量

图中的Java Heap是如下2项的和

  1. Dalvik Heap(ART申请的Buffer)
  2. .art mmap(ART map的buffer)

通过dumpsys meminfo我们能知道某个进程Java Heap的总大小,但这还不够,留下2个疑问:

  1. dumpsys meminfo显示的是总的Java Heap用量,如何breakdown?
  2. 如何知道申请的这8692KB java heap在代码中的callstack?

这就引出了下面两个Perfetto相关的主题

  • Java Heap Dumps
  • Java Heap Sampling

Java Heap Dumps – 对Java Heap进行Breakdown

Java Heap Dumps概述

Java Heap Dumps保留所有Java对象间的引用(retained)关系(非callstack),也就是GC不掉的对象,通过火焰图将这些对象呈现出来。

这里的引用定义为:ObjectX对象通过成员变量Z 引用 N Bytes的ObjectY对象

Java Heap Dumps概述

一般来说,一个对象可以通过多条路径访问,Java Heap Dumps只显示最短路径

更具体的Java Heap Dumps保留的是下图Obj1/Obj2/Obj3 不可回收的部分:

Java Heap Dumps概述

Java Heap Dumps 配置文件说明

参考:https://s.deepinout.com/android-14.0.0_r2/xref/external/perfetto/protos/perfetto/config/profiling/java_hprof_config.proto

常用的配置如下,这里是对高通Camera App进行dump,dump的时间间隔为500ms

data_sources: {
    config {
        name: "android.java_hprof"
        target_buffer: 0
        java_hprof_config {
            process_cmdline: "org.codeaurora.snapcam"
            continuous_dump_config {
                dump_phase_ms: 5
                dump_interval_ms: 500
            }
        }
    }
}

能配置的字段说明如下:

Field Description
process_cmdline 字符串类型,要抓取的命令行白名单列表,与 /proc//cmdline 进行匹配,例如: process_cmdline: “com.deepinout.geekcamera2” process_cmdline: “com.android.camera2”
pid Uint64类型,要抓取的pid白名单列表,例如: pid: 5858 pid: 5599
target_installed_by Android12上支持,字符串类型,指定允许profile的分区
min_anonymous_memory_kb Uint32类型,不profile (anon RSS + swap < given value) 小于指定大小的进程
dump_smaps Bool类型,是否dump smaps(/proc/self/smaps.)
ignored_types 字符串类型,从profile中排出不感兴趣的对象,比如” sun.misc.Cleaner”

ContinuousDumpConfig如下:

Field Description
dump_phase_ms Uint32类型,在第一个连续dump之前等待的毫秒数。
dump_interval_ms Uint32类型,相邻两次dump的时间间隔
scan_pids_only_on_start Bool类型
如果为True,则扫描所有进程以查找 process_cmdline,并仅在数据源启动时按 min_anonymous_memory_kb 进行过滤。(Android S及以下默认值)
如果为False,则重新扫描所有进程以在每次dump时查找。(Android T及以上默认值)

从Perfetto分析Java Heap Dumps

如下图所示,dump完后通过Perfetto UI打开,就能看到这23.17MB不能被回收的Java Heap分别是由哪些部分组成:

从Perfetto分析Java Heap Dumps

其中,

Tab 描述
Size 某对象通过此路径到GC Root 引用了多少字节。
Objects 某对象通过此路径到GC Root 引用了多少对象。

Java Heap Sampling – Java Heap分配时的调用栈

Java Heap Sampling介绍

  • 通过采样方式,记录对象分配/创建时的callstacks,不包含对象释放/被GC回收的callstacks

  • Heapprofd通过Hook heap buffer的申请函数来完成heap分配采样(libc.malloc heap是hook C语言的malloc/free和C++的operator new/delete ),java 使用的com.android.art heap。

  • 给定一个n字节的采样间隔,平均每分配n字节就会对一个分配进行采样。默认的采样率是4096字节。

Java Heap Sampling配置

  • 运行tools/heap_profile命令时加上–heaps com.android.art (命令行方式)
  • 在HeapprofdConfig中加入heaps: "com.android.art"(Perfetto方式)
data_sources: {
    config {
        name: "android.heapprofd"
        target_buffer: 0
        heapprofd_config {
            sampling_interval_bytes: 4096
            process_cmdline: "org.codeaurora.snapcam"
            heaps: "com.android.art"
            continuous_dump_config {
                dump_phase_ms: 5
                dump_interval_ms: 500
            }
            block_client: false
        }
    }
}

从Perfetto分析Java Heap Sampling

从Perfetto分析Java Heap Dumps

Tab 描述
Total allocation Size 从开始dump到本次dump间,总共分配了多少内存(有的可能已经释放)
Total allocation count 从开始dump到本次dump间,总共执行了多少次内存分配(有的可能已经释放)

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程

Android Camera性能分析