5

While using Android Profiler to find memory leaks in an app running on Android 11 physical device, I noticed that the app holds memory in native heap even when it's in the background i.e. when no Activity or Service is running (cached state). This was tested with both debug and release builds of the app. It's not due to bitmaps. Neither the app uses JNI code, except that loaded by the framework.

This is what dumpsys meminfo <PID> shows:

...
                   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
...

And this is what I found in /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

Note the 80 MB PSS: Native Heap 80769 and 80629 [anon:scudo:primary]. This is more than 60% (and sometimes more than 70%) of the total held PSS. While for other apps running on the device the average is 25%.

So I did app startup profiling using Perfetto native heap profiler:

And it shows memory allocations mainly for /memfd:jit-cache (deleted) (90%), due to String.matches calls. Nothing else is recorded.

Malloc Debug (am dumpheap -n) also dumps only around 30 MB of memory.

A forced garbage collection makes no difference. I have also gone through the related questions like this and this but they are not helpful.

I also checked scudo documentation and the source code but could not find any helpful hints.

How to debug this possible leak in native memory?

Irfan Latif
  • 498
  • 2
  • 9
  • 24

0 Answers0