android 内存分析之native

139 阅读2分钟

link from Debugging memory usage on Android - Perfetto Tracing Docs **
Native Heap Profiles require Android 10.**

NOTE: For detailed instructions about the native heap profiler and troubleshooting see the Data sources > Heap profiler page.

Applications usually get memory through malloc or C++'s new rather than directly getting it from the kernel. The allocator makes sure that your memory is more efficiently handled (i.e. there are not many gaps) and that the overhead from asking the kernel remains low.

We can log the native allocations and frees that a process does using heapprofd. The resulting profile can be used to attribute memory usage to particular function callstacks, supporting a mix of both native and Java code. The profile will only show allocations done while it was running, any allocations done before will not be shown.

Capturing the profile

Use the tools/heap_profile script to profile a process. If you are having trouble make sure you are using the latest version. See all the arguments using tools/heap_profile -h, or use the defaults and just profile a process (e.g. system_server):

$ tools/heap_profile -n system_server Profiling active. Press Ctrl+C to terminate. You may disconnect your device. Wrote profiles to /tmp/profile-1283e247-2170-4f92-8181-683763e17445 (symlink /tmp/heap_profile-latest) These can be viewed using pprof. Googlers: head to pprof/ and upload them.

When you see Profiling active, play around with the phone a bit. When you are done, press Ctrl-C to end the profile. For this tutorial, I opened a couple of apps.

Viewing the data

Then upload the raw-trace file from the output directory to the Perfetto UI and click on diamond marker that shows.

Profile Diamond

The tabs that are available are

  • Unreleased malloc size: how many bytes were allocated but not freed at this callstack the moment the dump was created.
  • Total malloc size: how many bytes were allocated (including ones freed at the moment of the dump) at this callstack.
  • Unreleased malloc count: how many allocations without matching frees were done at this callstack.
  • Total malloc count: how many allocations (including ones with matching frees) were done at this callstack.

The default view will show you all allocations that were done while the profile was running but that weren't freed (the space tab).

Native Flamegraph

We can see that a lot of memory gets allocated in paths through AssetManager.applyStyle. To get the total memory that was allocated this way, we can enter "applyStyle" into the Focus textbox. This will only show callstacks where some frame matches "applyStyle".

Native Flamegraph with Focus

From this we have a clear idea where in the code we have to look. From the code we can see how that memory is being used and if we actually need all of it.

link from Debugging memory usage on Android - Perfetto Tracing Docs