Quick assessment tools

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 Dirty
    • Private 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 dumpsys example, almost all of the Native Heap and Dalvik Heap have been moved to ZRAM.
  • App Summary: A higher-level categorization combining the detailed rows into understandable buckets.
  • Objects: Useful for tracking leaked Activities and ViewRootImpl instances. If you back out of your app and force a GC, the Activities count should return to 0.

Hands-on exercise: quick triage with meminfo

This exercise shows how different types of allocations show up in meminfo.

  1. Launch the app:

    adb shell am start -W -n com.android.memorylab/.MainActivity
    
  2. Check baseline memory:

    adb shell dumpsys meminfo -s com.android.memorylab
    

    (The -s flag provides a short, concise summary of memory categories).

  3. Allocate Java Memory: Tap the Allocate Java Memory (10MB) button 3 times in the app.