Index: components/tracing/docs/heap_profiler.md |
diff --git a/components/tracing/docs/heap_profiler.md b/components/tracing/docs/heap_profiler.md |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ba244ce4e6b3390dc66a5acd0e8915dab4ac9926 |
--- /dev/null |
+++ b/components/tracing/docs/heap_profiler.md |
@@ -0,0 +1,114 @@ |
+# Heap Profiling with MemoryInfra |
+ |
+As of Chrome 48, MemoryInfra supports heap profiling. The core principle is |
+a solution that JustWorks™ on all platforms without patching or rebuilding, |
+intergrated with the chrome://tracing ecosystem. |
+ |
+[TOC] |
+ |
+## How to Use |
+ |
+ 1. Start Chrome with the `--enable-heap-profiling` switch. This will make |
+ Chrome keep track of all allocations. |
+ |
+ 2. Grab a [MemoryInfra][memory-infra] trace. For best results, start tracing |
+ first, and _then_ open a new tab that you want to trace. Furthermore, |
+ enabling more categories (besides memory-infra) will yield more detailed |
+ information in the heap profiler backtraces. |
+ |
+ 3. When the trace has been collected, select a heavy memory dump indicated by |
+ a purple ![M][m-purple] dot. Heap dumps are only included in heavy memory |
+ dumps. |
+ |
+ 4. In the analysis view, cells marked with a triple bar icon (☰) contain heap |
+ dumps. Select such a cell. |
+ |
+ ![Cells containing a heap dump][cells-heap-dump] |
+ |
+ 5. Scroll down all the way to _Heap Details_. |
+ |
+ 6. Pinpoint the memory bug and live happily ever after. |
+ |
+[memory-infra]: memory_infra.md |
+[m-purple]: https://drive.google.com/uc?id=0Bx14iZPZRgb5RFFGc0xZZEJWVFk |
+[cells-heap-dump]: https://drive.google.com/uc?id=0Bx14iZPZRgb5NGlJSFRONTFoWEU |
+ |
+## Heap Details |
+ |
+The heap details view contains a tree that represents the heap. The size of the |
+root node corresponds to the selected allocator cell. |
+ |
+*** aside |
+The size value in the heap details view will not match the value in the selected |
+analysis view cell exactly. There are three reasons for this. First, the heap |
+profiler reports the memory that _the program requested_, whereas the allocator |
+reports the memory that it _actually allocated_ plus its own bookkeeping |
+overhead. Second, allocations that happen early --- before Chrome knows that |
+heap profiling is enabled --- are not captured by the heap profiler, but they |
+are reported by the allocator. Third, tracing overhead is not discounted by the |
+heap profiler. |
+*** |
+ |
+The heap can be broken down in two ways: by _backtrace_ (marked with an ƒ), and |
+by _type_ (marked with a Ⓣ). When tracing is enabled, Chrome records trace |
+events, most of which appear in the flame chart in timeline view. At every |
+point in time these trace events form a pseudo stack, and a vertical slice |
+through the flame chart is like a backtrace. This corresponds to the ƒ nodes in |
+the heap details view. Hence enabling more tracing categories will give a more |
+detailed breakdown of the heap. |
+ |
+The other way to break down the heap is by object type. At the moment this is |
+only supported for PartitionAlloc. |
+ |
+*** aside |
+In official builds, only the most common type names are included due to binary |
+size concerns. Development builds have full type information. |
+*** |
+ |
+To keep the trace log small, uninteresting information is omitted from heap |
+dumps. The long tail of small nodes is not dumped, but grouped in an `<other>` |
+node instead. Note that altough these small nodes are insignificant on their |
+own, together they can be responsible for a significant portion of the heap. The |
+`<other>` node is large in that case. |
+ |
+## Example |
+ |
+In the trace below, `ParseAuthorStyleSheet` is called at some point. |
+ |
+![ParseAuthorStyleSheet pseudo stack][pseudo-stack] |
+ |
+The pseudo stack of trace events corresponds to the tree of ƒ nodes below. Of |
+the 23.5 MiB of memory allocated with PartitionAlloc, 1.9 MiB was allocated |
+inside `ParseAuthorStyleSheet`, either directly, or at a deeper level (like |
+`CSSParserImpl::parseStyleSheet`). |
+ |
+![Memory Allocated in ParseAuthorStyleSheet][break-down-by-backtrace] |
+ |
+By expanding `ParseAuthorStyleSheet`, we can see which types were allocated |
+there. Of the 1.9 MiB, 371 KiB was spent on `ImmutableStylePropertySet`s, and |
+238 KiB was spent on `StringImpl`s. |
+ |
+![ParseAuthorStyleSheet broken down by type][break-down-by-type] |
+ |
+It is also possible to break down by type first, and then by backtrace. Below |
+we see that of the 23.5 MiB allocated with PartitionAlloc, 1 MiB is spent on |
+`Node`s, and about half of the memory spent on nodes was allocated in |
+`HTMLDocumentParser`. |
+ |
+![The PartitionAlloc heap broken down by type first and then by backtrace][type-then-backtrace] |
+ |
+Heap dump diffs are fully supported by trace viewer. Select a heavy memory dump |
+(a purple dot), then with the control key select a heavy memory dump earlier in |
+time. Below is a diff of theverge.com before and in the middle of loading ads. |
+We can see that 4 MiB were allocated when parsing the documents in all those |
+iframes, almost a megabyte of which was due to JavaScript. (Note that this is |
+memory allocated by PartitionAlloc alone, the total renderer memory increase was |
+around 72 MiB.) |
+ |
+![Diff of The Verge before and after loading ads][diff] |
+ |
+[pseudo-stack]: https://drive.google.com/uc?id=0Bx14iZPZRgb5M194Y2RqQjhoZkk |
+[break-down-by-backtrace]: https://drive.google.com/uc?id=0Bx14iZPZRgb5ZDRQdGNnNDNIazA |
+[break-down-by-type]: https://drive.google.com/uc?id=0Bx14iZPZRgb5THJMYlpyTEN2Q2s |
+[type-then-backtrace]: https://drive.google.com/uc?id=0Bx14iZPZRgb5UGZFX1pDUVpOLUU |
+[diff]: https://drive.google.com/uc?id=0Bx14iZPZRgb5UzNvMmVOa0RnQWs |