如何调查 Android 应用程序的本机堆分配?

Irf*_*tif 5 android profiling memory-leaks heap-memory

在使用 Android Profiler 查找在 Android 11 物理设备上运行的应用程序中的内存泄漏时,我注意到该应用程序即使在后台(即没有运行任何 Activity 或服务(缓存状态)时)也会将内存保留在本机堆中。这是通过应用程序的调试和发布版本进行测试的。这不是由于位图。除了由框架加载的代码之外,应用程序都不使用 JNI 代码。

dumpsys meminfo <PID>显示的是:

...
                   Pss  Private  Private  SwapPss      Rss     Heap     Heap     Heap
                 Total    Dirty    Clean    Dirty    Total     Size    Alloc     Free
                ------   ------   ------   ------   ------   ------   ------   ------
  Native Heap    80769    80708        0       58    81384   207724    22890   180724
  Dalvik Heap     7093     7004        0       41     7684    14178     5986     8192
  ...
        TOTAL   128567   117212     2676      188   128567   221902    28876   188916
...
Run Code Online (Sandbox Code Playgroud)

这就是我发现的/proc/<PID>/smaps

...
730       [anon:dalvik-/system/framework/boot-telephony-common.art]
962       /system/framework/framework-res.apk
1159      /system/framework/framework.jar
1349      [anon:dalvik-/apex/com.android.art/javalib/boot.art]
1992      /memfd:jit-cache (deleted)
2527      [anon:dalvik-zygote space]
3091      [anon:dalvik-LinearAlloc]
3924      [anon:dalvik-main space (region space)]
4048      /dev/kgsl-3d0
5965      [anon:dalvik-/system/framework/boot-framework.art]
9896      [anon:dalvik-classes.dex extracted in memory from /data/app/.../base.apk]
80629     [anon:scudo:primary]

128169 kB
Run Code Online (Sandbox Code Playgroud)

请注意 80 MB PSS:Native Heap 8076980629 [anon:scudo:primary]。这占 PSS 持有总量的 60% 以上(有时甚至超过 70%)。而对于设备上运行的其他应用程序,平均值为 25%。

因此,我使用Perfetto 本机堆分析器进行了应用程序启动分析:

它显示内存分配主要用于/memfd:jit-cache (deleted)(90%),由于String.matches调用。没有其他任何记录。

Malloc 调试( am dumpheap -n) 也仅转储大约 30 MB 的内存。

强制垃圾回收没有任何区别。我也经历过类似这样的相关问题,但它们没有帮助。

我还检查了scudo 文档源代码,但找不到任何有用的提示。

如何调试本机内存中可能的泄漏?