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