Albert J. Wong | 34b06ef | 2018-01-11 18:57:26 | [diff] [blame] | 1 | # Description of Tools for developers trying to understand memory usage |
| 2 | |
| 3 | This page provides an overview of the tools available for examining memory usage |
| 4 | in chrome. |
| 5 | |
Albert J. Wong | 2db98ee2 | 2018-01-16 23:17:07 | [diff] [blame] | 6 | ## Which tool should I use? |
Albert J. Wong | 34b06ef | 2018-01-11 18:57:26 | [diff] [blame] | 7 | |
| 8 | No single tool can give a full view of memory usage in Chrome. There are too |
| 9 | many different context involved (JS heap, DOM objects, native allocations, GPU, |
| 10 | etc) that any tool that collected all that information likely would not be able |
Albert J. Wong | 2db98ee2 | 2018-01-16 23:17:07 | [diff] [blame] | 11 | to provide an actionable analysis. |
| 12 | |
| 13 | Here is a table of common area of inquiry and suggested tools for examining them. |
Albert J. Wong | 34b06ef | 2018-01-11 18:57:26 | [diff] [blame] | 14 | |
Albert J. Wong | 17417476 | 2018-01-18 23:50:23 | [diff] [blame] | 15 | | Topic/Area of Inquiry | Tool(s) | |
| 16 | |----------------------- | ------- | |
| 17 | | Which subsystems consuming memory per process. | [Global Memory Dumps](#global-memory-dumps), [Taking memory-infra trace](#memory-infra-trace) | |
| 18 | | Tracking C++ object allocation over time | [`diff_heap_profiler.py`](#diff-heap-profiler), [Heap Details in chrome://tracing](#heap-dumps-chrome-tracing) | |
Kevin Babbitt | dfa8c8c | 2023-11-16 16:41:40 | [diff] [blame] | 19 | | Suspected DOM leaks in the Renderer | [Developer Tools Heap Snapshots](#dev-tools-heap-snapshots), [Real World Leak Detector](#real-world-leak-detector) | |
Albert J. Wong | 17417476 | 2018-01-18 23:50:23 | [diff] [blame] | 20 | | Kernel/Driver Memory and Resource Usage | [perfmon (win), ETW](#os-tools) | |
Albert J. Wong | 2db98ee2 | 2018-01-16 23:17:07 | [diff] [blame] | 21 | | Blackbox examination of process memory | [VMMAP (win)](#os-tools) | Understanding fragmentation of the memory space | |
Albert J. Wong | 17417476 | 2018-01-18 23:50:23 | [diff] [blame] | 22 | | Symbolized Heap Dump data | [Heap Dumps](#heap-dumps) | Grabs raw data for analysis by other tools | |
Albert J. Wong | 2db98ee2 | 2018-01-16 23:17:07 | [diff] [blame] | 23 | |
| 24 | If that seems like a lot of tools and complexity, it is [but there's a reason](#no-one-true-metric). |
| 25 | |
Albert J. Wong | 17417476 | 2018-01-18 23:50:23 | [diff] [blame] | 26 | ----------- |
| 27 | ## <a name="global-memory-dumps"> Global Memory Dumps |
Albert J. Wong | 3948511 | 2018-01-17 23:07:51 | [diff] [blame] | 28 | Many Chrome subsystems implement the |
Amos Lim | f916d57 | 2018-05-21 23:10:35 | [diff] [blame] | 29 | [`trace_event::MemoryDumpProvider`](../../base/trace_event/memory_dump_provider.h) |
Albert J. Wong | 3948511 | 2018-01-17 23:07:51 | [diff] [blame] | 30 | interface to provide self-reported stats detailing their memory usage. The |
Albert J. Wong | 17417476 | 2018-01-18 23:50:23 | [diff] [blame] | 31 | Global Memory Dump view provides a snapshot-oriented view of these subsystems |
| 32 | that can be collected and viewed via the chrome://tracing infrastructure. |
Albert J. Wong | 3948511 | 2018-01-17 23:07:51 | [diff] [blame] | 33 | |
| 34 | In the Analysis split screen, a single roll-up number is provided for each of |
| 35 | these subsystems. This can give a quick feel for where memory is allocated. The |
| 36 | cells can then be clicked to drill into a more detailed view of the subsystem's |
| 37 | stats. The memory-infra docs have more [detailed descriptions for each column](../memory-infra#Columns). |
| 38 | |
| 39 | To look a the delta between two dumps, control-click two different dark-purple M |
| 40 | circles. |
| 41 | |
| 42 | ### Blindspots |
Quinten Yearsley | 317532d | 2021-10-20 17:10:31 | [diff] [blame] | 43 | * Statistics are self-reported. If the MemoryDumpProvider implementation does |
Albert J. Wong | 3948511 | 2018-01-17 23:07:51 | [diff] [blame] | 44 | not fully cover the resource usage of the subsystem, those resources will |
| 45 | not be accounted. |
| 46 | |
| 47 | ### Instructions |
| 48 | 1. Take a memory-infra trace |
| 49 | 2. Click on a *dark-purple* M circle. Each one of these corresponds to a heavy |
| 50 | dump. |
| 51 | 3. Click on a (process, subsystem) cell in `Global Memory Dump` tab within the |
| 52 | Analysis View in bottom split screen. |
| 53 | 4. *Scroll down* to the bottom of the lower split screen to see details of |
| 54 | selection (process, subsystem) |
| 55 | |
| 56 | Clicking on the cell pulls up a view that lets you examine the stats |
| 57 | collected by the given MemoryDumpProvider however that view is often way outside |
| 58 | the viewport of the analysis view. Be sure to scroll down. |
| 59 | |
| 60 | |
Albert J. Wong | 17417476 | 2018-01-18 23:50:23 | [diff] [blame] | 61 | ----------- |
| 62 | ## <a name="heap-dumps-chrome-tracing"> Heap Dumps in chrome://tracing |
| 63 | GUI method of exploring the heap dump for a process. |
Albert J. Wong | 3948511 | 2018-01-17 23:07:51 | [diff] [blame] | 64 | |
Albert J. Wong | 17417476 | 2018-01-18 23:50:23 | [diff] [blame] | 65 | TODO(awong): Explain how to interpret + interact with the data. (e.g. threads, |
| 66 | bottom-up vs top-down, etc) |
Albert J. Wong | 3948511 | 2018-01-17 23:07:51 | [diff] [blame] | 67 | |
| 68 | ### Blindspots |
Albert J. Wong | 17417476 | 2018-01-18 23:50:23 | [diff] [blame] | 69 | * As this is a viewer of [heap dump](#heap-dump) data, it has the same |
| 70 | blindspots. |
| 71 | * The tool is bound by the memory limits of chrome://tracing. Large dumps |
| 72 | (which generate large JS strings) will not be loadable and may likely crash |
| 73 | chrome://tracing. |
Albert J. Wong | 3948511 | 2018-01-17 23:07:51 | [diff] [blame] | 74 | |
| 75 | ### Instructions |
Albert J. Wong | 17417476 | 2018-01-18 23:50:23 | [diff] [blame] | 76 | 1. [Configure Out-of-process heap profiling](#configure-oophp) |
Albert J. Wong | 3948511 | 2018-01-17 23:07:51 | [diff] [blame] | 77 | 2. Take a memory-infra trace and symbolize it. |
| 78 | 3. Click on a *dark-purple* M circle. |
| 79 | 4. Find the cell corresponding to the allocator (list below) for the process of interest within the `Global Memory Dump` tab of the Analysis View. |
| 80 | 5. Click on "hotdog" menu icon next to the number. If no icon is shown, the |
| 81 | trace does not contain a heap dump for that allocator. |
| 82 | 6. *Scroll down* to the bottom of the lower split screen. There should now |
| 83 | be a "Heap details" section below the "Component details" section that |
| 84 | shows a all heap allocations in a navigatable format. |
| 85 | |
| 86 | On step 5, the `Component Details` and `Heap Dump` views that let you examine |
| 87 | the information collected by the given MemoryDumpProvider is often way outside |
| 88 | the current viewport of the Analysis View. Be sure to scroll down! |
| 89 | |
Albert J. Wong | 3948511 | 2018-01-17 23:07:51 | [diff] [blame] | 90 | Currently supported allocators: malloc, PartitionAlloc, Oilpan. |
| 91 | |
| 92 | Note: PartitionAlloc and Oilpan traces have unsymbolized Javascript frames |
| 93 | which often make exploration via this tool hard to consume. |
| 94 | |
Albert J. Wong | 2db98ee2 | 2018-01-16 23:17:07 | [diff] [blame] | 95 | |
Albert J. Wong | 17417476 | 2018-01-18 23:50:23 | [diff] [blame] | 96 | ----------- |
| 97 | |
| 98 | ## <a name="diff-heap-profiler"></a> `diff_heap_profiler.py` |
| 99 | This is most useful for examining allocations that occur during an interval of |
| 100 | time. This is often useful for finding leaks as one call-stack will rise to the |
| 101 | top as the leak is repeated triggered. |
| 102 | |
| 103 | Multiple traces can be given at once to show incremental changes. A similar |
| 104 | analysis can be had via ctrl-clicking multiple Global Memory Dumps in the |
| 105 | chrome://tracing UI but loading multiiple detailed heapdumps can often crash the |
| 106 | chrome://tracing UI. This tool is more robust to large data sizes. |
| 107 | |
| 108 | The source code can also be used as an example for manually processing heap dump |
| 109 | data in python. |
| 110 | |
| 111 | TODO(awong): Write about options to script and the flame graph. |
| 112 | |
| 113 | ### Blindspots |
| 114 | * As this is a viewer of [heap dump](#heap-dumps) data, it has the same |
| 115 | blindspots. |
| 116 | |
| 117 | ### Instructions |
| 118 | 1. Get 2 or more [symbolized heap dump](#heap-dumps) |
John Palmer | 046f987 | 2021-05-24 01:24:56 | [diff] [blame] | 119 | 3. Run resulting traces through [`diff_heap_profiler.py`](https://chromium.googlesource.com/catapult/+/main/experimental/tracing/bin/diff_heap_profiler.py) to show a list of new allocations. |
Albert J. Wong | 17417476 | 2018-01-18 23:50:23 | [diff] [blame] | 120 | |
| 121 | ----------- |
| 122 | ## <a name="heap-dumps"></a>Heap Dumps |
| 123 | Heap dumps provide extremely detailed data about object allocations and is |
| 124 | useful for finding code locations that are generating a large number of live |
| 125 | allocations. Data is tracked and recorded using the [Out-of-process Heap |
Amos Lim | f916d57 | 2018-05-21 23:10:35 | [diff] [blame] | 126 | Profiler (OOPHP)](../../components/services/heap_profiling/README.md). |
Albert J. Wong | 17417476 | 2018-01-18 23:50:23 | [diff] [blame] | 127 | |
| 128 | For the Browser and GPU process, this often quickly finds objects that leak over |
| 129 | time. |
| 130 | |
| 131 | This is less useful in the Renderer process. Even though Oilpan and |
| 132 | PartitionAlloc are hooked into the data collection, many of the stacks end up |
| 133 | looking similar due to the nature of DOM node allocation. |
| 134 | |
| 135 | ### Blindspots |
| 136 | * Heap dumps only catch allocations that pass through the allocator shim. In particular, |
| 137 | calls made directly to the platform's VM subsystem (eg, via `mmap()` or |
| 138 | `VirtualAlloc()`) will not be tracked. |
| 139 | * Utility processes are currently not profiled. |
| 140 | * Allocations are only recorded after the |
Amos Lim | f916d57 | 2018-05-21 23:10:35 | [diff] [blame] | 141 | [HeapProfilingService](../../components/services/heap_profiling/heap_profiling_service.h) |
erikchen | fa983faa | 2018-04-05 18:56:42 | [diff] [blame] | 142 | has spun up the profiling process and created a connection to the target |
| 143 | process. The HeapProfilingService is a mojo service that can be configured to |
| 144 | start early in browser startup but it still takes time to spin up and early |
| 145 | allocations are thus lost. |
Albert J. Wong | 17417476 | 2018-01-18 23:50:23 | [diff] [blame] | 146 | |
| 147 | ### Instructions |
| 148 | #### <a name="configure-oophp"></a>Configuration and setup |
| 149 | 1. [Android Only] For native stack traces, a custom build with |
Darwin Huang | 6ba4756 | 2019-12-18 21:28:59 | [diff] [blame] | 150 | `enable_framepointers=true` is required. |
Albert J. Wong | 17417476 | 2018-01-18 23:50:23 | [diff] [blame] | 151 | 2. Configure OOPHP settings in about://flags. (See table below) |
| 152 | 3. Restart browser with new settings if necessary. |
| 153 | 4. Verify target processes are being profiled in chrome://memory-internals. |
| 154 | 5. [Optional] start profiling additional processes in chrome://memory-internals. |
| 155 | |
| 156 | | Flag | Notes | |
| 157 | | ------- | ----- | |
| 158 | | Out of process heap profiling start mode. | This option is somewhat misnamed. It tells OOPHP which processes to profile at startup. Other processes can selected manually later via chrome://memory-internals even if this is set to "disabled". | |
| 159 | | Keep track of even the small allocations in memlog heap dumps. | By default, small allocations are not emitted in the heap dump to reduce dump size. Enabling this track _all_ allocations. | |
Quinten Yearsley | 317532d | 2021-10-20 17:10:31 | [diff] [blame] | 160 | | The type of stack to record for memlog heap dumps | If possible, use Native stack frames as that provides the best information. When those are not available either due to performance for build (eg, no frame-pointers on arm32 official) configurations, using trace events for a "pseudo stack" can give good information too. | |
Albert J. Wong | 17417476 | 2018-01-18 23:50:23 | [diff] [blame] | 161 | | Heap profiling | Deprecated. Enables the in-process heap profiler. Functionality should be fully subsumed by preceeding options. | |
| 162 | |
| 163 | #### Saving a heap dump |
| 164 | 1. On Desktop, click "save dump" in chrome://memory-internals to save a |
| 165 | dump of all the profiled processes. On Android, enable debugging via USB |
| 166 | and use chrome://inspect/?tracing#devices to take a memory-infra trace |
| 167 | which will have the heap dump embedded. |
Erik Chen | fdf9afc | 2018-01-23 20:19:35 | [diff] [blame] | 168 | 2. Symbolize trace using [`symbolize_trace.py`](../../third_party/catapult/tracing/bin/symbolize_trace). If the Chrome binary was built locally, pass the flag "--is-local-build". |
Albert J. Wong | 17417476 | 2018-01-18 23:50:23 | [diff] [blame] | 169 | 3. Analyze resuing heap dump using [`diff_heap_profiler.py`](#diff-heap-profiler), or [Heap Profile view in Chrome Tracing](#tracing-heap-profile) |
| 170 | |
Quinten Yearsley | 317532d | 2021-10-20 17:10:31 | [diff] [blame] | 171 | On desktop, using chrome://memory-internals to take a heap dump is more reliable |
Albert J. Wong | 17417476 | 2018-01-18 23:50:23 | [diff] [blame] | 172 | as it directly saves the heapdump to a file instead of passing the serialized data |
| 173 | through the chrome://tracing renderer process which can easily OOM. For Android, |
| 174 | this native file saving was harder to implement and would still leave the |
| 175 | problem of getting the dump off the phone so memory-infra tracing is the |
| 176 | current recommended path. |
| 177 | |
| 178 | ----------- |
| 179 | ## <a name="memory-infra-trace"></a> Taking a memory-infra trace. |
| 180 | Examining self-reported statistics from various subsystems on memory usages. |
| 181 | This is most useful for getting a high-level understanding of how memory is |
| 182 | distributed between the different heaps and subsystems in chrome. |
| 183 | |
| 184 | It also provides a way to view heap dump allocation information collected per |
| 185 | process through a progressively expanding stack trace. |
| 186 | |
| 187 | Though chrome://tracing itself is a timeline based plot, this data is snapshot |
| 188 | oriented. Thus the standard chrome://tracing plotting tools do not provide a |
| 189 | good means for measuring changes per snapshot. |
| 190 | |
| 191 | ### Blindspots |
| 192 | * Statistics are self-reported via "Memory Dump Provider" interfaces. If there |
| 193 | is an error in the data collection, or if there are privileged resources |
| 194 | that cannot be easily measured from usermode, they will be missed. |
| 195 | |
| 196 | ### Instructions |
| 197 | 1. Visit chrome://tracing |
| 198 | 2. Start a trace for memory-infra |
| 199 | 1. Click the "Record" button |
| 200 | 2. Choose "Manually select settings" |
| 201 | 3. [optional] Clear out all other tracing categories. |
| 202 | 4. Select "memory-infra" from the "Disabled by Default Categories" |
| 203 | 5. Click record again. |
| 204 | 3. Wait for a few seconds for a Global Memory Dump to be taken. If OOPHP |
| 205 | is enabled, don't run for more than a few seconds to avoid crashing the |
| 206 | chrome://tracing UI with an over-large trace. |
| 207 | 4. Wait for a few seconds for a Global Memory Dump to be taken. |
| 208 | 5. Click stop |
| 209 | |
| 210 | This should produce a view of the trace file with periodic "light" and "heavy" |
| 211 | memory dumps. These dumps are created periodically so the time spent waiting |
| 212 | in step (3) determines how many dumps (which are snapshots) are taken. |
| 213 | |
| 214 | **Warning:** If OOPHP is enabled, the tracing UI may not be able to handle |
|
|