1# Memory: Java heap profiler 2 3NOTE: The Java heap profiler requires Android 11 or higher 4 5See the [Memory Guide](/docs/case-studies/memory.md#java-hprof) for getting 6started with Java heap profiling. 7 8Conversely from the [Native heap profiler](native-heap-profiler.md), the Java 9heap profiler reports full retention graphs of managed objects but not 10call-stacks. The information recorded by the Java heap profiler is of the form: 11_Object X retains object Y, which is N bytes large, through its class member 12named Z_. 13 14## UI 15 16Heap graph dumps are shown as flamegraphs in the UI after clicking on the 17diamond in the _"Heap Profile"_ track of a process. Each diamond corresponds to 18a heap dump. 19 20 21 22 23 24## SQL 25 26Information about the Java Heap is written to the following tables: 27 28* [`heap_graph_class`](/docs/analysis/sql-tables.autogen#heap_graph_class) 29* [`heap_graph_object`](/docs/analysis/sql-tables.autogen#heap_graph_object) 30* [`heap_graph_reference`](/docs/analysis/sql-tables.autogen#heap_graph_reference) 31 32For instance, to get the bytes used by class name, run the following query. 33As-is this query will often return un-actionable information, as most of the 34bytes in the Java heap end up being primitive arrays or strings. 35 36```sql 37select c.name, sum(o.self_size) 38 from heap_graph_object o join heap_graph_class c on (o.type_id = c.id) 39 where reachable = 1 group by 1 order by 2 desc; 40``` 41 42|name |sum(o.self_size) | 43|--------------------|--------------------| 44|java.lang.String | 2770504| 45|long[] | 1500048| 46|int[] | 1181164| 47|java.lang.Object[] | 624812| 48|char[] | 357720| 49|byte[] | 350423| 50 51We can use `experimental_flamegraph` to normalize the graph into a tree, always 52taking the shortest path to the root and get cumulative sizes. 53Note that this is **experimental** and the **API is subject to change**. 54From this we can see how much memory is being held by each type of object 55 56```sql 57select name, cumulative_size 58 from experimental_flamegraph(56785646801, 1, 'graph') 59 order by 2 desc; 60``` 61 62| name | cumulative_size | 63|------|-----------------| 64|java.lang.String|1431688| 65|java.lang.Class<android.icu.text.Transliterator>|1120227| 66|android.icu.text.TransliteratorRegistry|1119600| 67|com.android.systemui.statusbar.phone.StatusBarNotificationPresenter$2|1086209| 68|com.android.systemui.statusbar.phone.StatusBarNotificationPresenter|1085593| 69|java.util.Collections$SynchronizedMap|1063376| 70|java.util.HashMap|1063292| 71 72## TraceConfig 73 74The Java heap profiler is configured through the 75[JavaHprofConfig](/docs/reference/trace-config-proto.autogen#JavaHprofConfig) 76section of the trace config. 77 78```protobuf 79data_sources { 80 config { 81 name: "android.java_hprof" 82 java_hprof_config { 83 process_cmdline: "com.google.android.inputmethod.latin" 84 dump_smaps: true 85 } 86 } 87} 88``` 89