When you need to investigate memory usage, start with high-level assessment tools to identify which categories of memory are most significant.
dumpsys meminfo
The most common way to get an overview of an application's memory usage is
dumpsys meminfo. To see a detailed breakdown including all memory mappings, it
is often helpful to include the -a flag:
adb shell dumpsys meminfo -a <package_name_or_pid>
Here is a sample output from an application under some memory pressure (notice the high SwapPss):
** MEMINFO in pid 4562 [com.android.memorylab] **
Pss Private Private SwapPss Rss Heap Heap Heap
Total Dirty Clean Dirty Total Size Alloc Free
------ ------ ------ ------ ------ ------ ------ ------
Native Heap 394 268 64 17440 4264 29416 18128 8040
Dalvik Heap 165 8 0 672 8196 40949 32757 8192
Dalvik Other 47 28 0 604 1132
Stack 112 108 4 312 120
...
TOTAL 33197 580 788 21920 167776 70365 50885 16232
App Summary
Pss(KB) Rss(KB)
------ ------
Java Heap: 12 32608
Native Heap: 268 4264
Code: 724 125672
Stack: 108 120
Graphics: 0 0
Private Other: 256
System: 31829
Unknown: 5112
TOTAL PSS: 33197 TOTAL RSS: 167776 TOTAL SWAP PSS: 21920
Objects
Views: 15 ViewRootImpl: 1
AppContexts: 5 Activities: 1
...
Interpreting the data
- Pss Total: The Proportional Set Size. This is the sum of
Private DirtyPrivate Clean+ your process's equitable share of memory shared with other processes (like the Zygote boot image). This is the best metric for "how much memory is this app responsible for."
- Private Dirty: This is RAM that only your process is using and has been modified (or is anonymous memory). This is the most critical number for finding leaks because this memory cannot be dropped.
- Private Clean: RAM that only your process is using, but is an unmodified copy of a file on storage (like a DEX file). It can be dropped by the OS if memory is low.
- SwapPss: Memory that has been compressed and swapped into ZRAM. This can
happen either because the system is under memory pressure or because the
Android Runtime has identified background processes to compact (moving their
unused or inactive pages to ZRAM). In the
dumpsysexample, almost all of theNative HeapandDalvik Heaphave been moved to ZRAM.
- App Summary: A higher-level categorization combining the detailed rows into understandable buckets.
- Objects: Useful for tracking leaked
ActivitiesandViewRootImplinstances. If you back out of your app and force a GC, theActivitiescount should return to 0.
Hands-on exercise: quick triage with meminfo
This exercise shows how different types of allocations show up in meminfo.
Launch the app:
adb shell am start -W -n com.android.memorylab/.MainActivityCheck baseline memory:
adb shell dumpsys meminfo -s com.android.memorylab(The
-sflag provides a short, concise summary of memory categories).Allocate Java Memory: Tap the Allocate Java Memory (10MB) button 3 times in the app.