1# Memory: Java heap dumps 2 3NOTE: Capturing Java heap dumps requires Android 11 or higher 4 5See the [Memory Guide](/docs/case-studies/memory.md#java-hprof) for getting 6started with Java heap dumps. 7 8Conversely from [Native heap profiles](native-heap-profiler.md), Java heap dumps 9report full retention graphs of managed objects but not call-stacks. The 10information recorded in a Java heap dump is of the form: _Object X retains 11object Y, which is N bytes large, through its class member named Z_. 12 13Java heap dumps are not to be confused with profiles taken by the 14[Java heap sampler](native-heap-profiler.md#java-heap-sampling) 15 16## UI 17 18Heap graph dumps are shown as flamegraphs in the UI after clicking on the 19diamond in the _"Heap Profile"_ track of a process. Each diamond corresponds to 20a heap dump. 21 22 23 24 25 26The native size of certain objects is represented as an extra child node in the 27flamegraph, prefixed with "[native]". The extra node counts as an extra object. 28This is available only on Android 13 or higher. 29 30## SQL 31 32Information about the Java Heap is written to the following tables: 33 34* [`heap_graph_class`](/docs/analysis/sql-tables.autogen#heap_graph_class) 35* [`heap_graph_object`](/docs/analysis/sql-tables.autogen#heap_graph_object) 36* [`heap_graph_reference`](/docs/analysis/sql-tables.autogen#heap_graph_reference) 37 38`native_size` (available only on Android T+) is extracted from the related 39`libcore.util.NativeAllocationRegistry` and is not included in `self_size`. 40 41For instance, to get the bytes used by class name, run the following query. 42As-is this query will often return un-actionable information, as most of the 43bytes in the Java heap end up being primitive arrays or strings. 44 45```sql 46select c.name, sum(o.self_size) 47 from heap_graph_object o join heap_graph_class c on (o.type_id = c.id) 48 where reachable = 1 group by 1 order by 2 desc; 49``` 50 51|name |sum(o.self_size) | 52|--------------------|--------------------| 53|java.lang.String | 2770504| 54|long[] | 1500048| 55|int[] | 1181164| 56|java.lang.Object[] | 624812| 57|char[] | 357720| 58|byte[] | 350423| 59 60We can use `experimental_flamegraph` to normalize the graph into a tree, always 61taking the shortest path to the root and get cumulative sizes. 62Note that this is **experimental** and the **API is subject to change**. 63From this we can see how much memory is being held by each type of object 64 65For that, we need to find the timestamp and upid of the graph. 66 67```sql 68select distinct graph_sample_ts, upid from heap_graph_object 69``` 70 71|graph_sample_ts | upid | 72|--------------------|--------------------| 73| 56785646801 | 1 | 74 75We can then use them to get the flamegraph data. 76 77```sql 78select name, cumulative_size 79from experimental_flamegraph( 80 -- The type of the profile from which the flamegraph is being generated. 81 -- Always 'graph' for Java heap graphs. 82 'graph', 83 -- The timestamp of the heap graph sample. 84 56785646801, 85 -- Timestamp constraints: not relevant and always null for Java heap graphs. 86 NULL, 87 -- The upid of the heap graph sample. 88 1, 89 -- The upid group: not relevant and always null for Java heap graphs. 90 NULL, 91 -- A regex for focusing on a particular node in the heapgraph: for advanced 92 -- use only. 93 NULL 94) 95order by 2 desc; 96``` 97 98| name | cumulative_size | 99|------|-----------------| 100|java.lang.String|1431688| 101|java.lang.Class<android.icu.text.Transliterator>|1120227| 102|android.icu.text.TransliteratorRegistry|1119600| 103|com.android.systemui.statusbar.phone.StatusBarNotificationPresenter$2|1086209| 104|com.android.systemui.statusbar.phone.StatusBarNotificationPresenter|1085593| 105|java.util.Collections$SynchronizedMap|1063376| 106|java.util.HashMap|1063292| 107 108## TraceConfig 109 110The Java heap dump data source is configured through the 111[JavaHprofConfig](/docs/reference/trace-config-proto.autogen#JavaHprofConfig) 112section of the trace config. 113 114```protobuf 115data_sources { 116 config { 117 name: "android.java_hprof" 118 java_hprof_config { 119 process_cmdline: "com.google.android.inputmethod.latin" 120 dump_smaps: true 121 } 122 } 123} 124``` 125