| OLD | NEW |
| 1 # Heap Profiler Internals | 1 # Heap Profiler Internals |
| 2 | 2 |
| 3 This document describes how the heap profiler works and how to add heap | 3 This document describes how the heap profiler works and how to add heap |
| 4 profiling support to your allocator. If you just want to know how to use it, | 4 profiling support to your allocator. If you just want to know how to use it, |
| 5 see [Heap Profiling with MemoryInfra](heap_profiler.md) | 5 see [Heap Profiling with MemoryInfra](heap_profiler.md) |
| 6 | 6 |
| 7 [TOC] | 7 [TOC] |
| 8 | 8 |
| 9 ## Overview | 9 ## Overview |
| 10 | 10 |
| 11 The heap profiler consists of tree main components: | 11 The heap profiler consists of tree main components: |
| 12 | 12 |
| 13 * **The Context Tracker**: Responsible for providing context (pseudo stack | 13 * **The Context Tracker**: Responsible for providing context (pseudo stack |
| 14 backtrace) when an allocation occurs. | 14 backtrace) when an allocation occurs. |
| 15 * **The Allocation Register**: A specialized hash table that stores allocation | 15 * **The Allocation Register**: A specialized hash table that stores allocation |
| 16 details by address. | 16 details by address. |
| 17 * **The Heap Dump Writer**: Extracts the most important information from a set | 17 * **The Heap Dump Writer**: Extracts the most important information from a set |
| 18 of recorded allocations and converts it into a format that can be dumped into | 18 of recorded allocations and converts it into a format that can be dumped into |
| 19 the trace log. | 19 the trace log. |
| 20 | 20 |
| 21 These components are designed to work well together, but to be usable | 21 These components are designed to work well together, but to be usable |
| 22 independently as well. | 22 independently as well. |
| 23 | 23 |
| 24 When there is a way to get notified of all allocations and frees, this is the | 24 When there is a way to get notified of all allocations and frees, this is the |
| 25 normal flow: | 25 normal flow: |
| 26 | 26 |
| 27 1. When an allocation occurs, call | 27 1. When an allocation occurs, call |
| 28 [`AllocationContextTracker::GetInstanceForCurrentThread()->GetContextSnapsho
t()`][context-tracker] | 28 [`AllocationContextTracker::GetContextSnapshot()`][context-tracker] |
| 29 to get an [`AllocationContext`][alloc-context]. | 29 to get an [`AllocationContext`][alloc-context]. |
| 30 2. Insert that context together with the address and size into an | 30 2. Insert that context together with the address and size into an |
| 31 [`AllocationRegister`][alloc-register] by calling `Insert()`. | 31 [`AllocationRegister`][alloc-register] by calling `Insert()`. |
| 32 3. When memory is freed, remove it from the register with `Remove()`. | 32 3. When memory is freed, remove it from the register with `Remove()`. |
| 33 4. On memory dump, collect the allocations from the register, call | 33 4. On memory dump, collect the allocations from the register, call |
| 34 [`ExportHeapDump()`][export-heap-dump], and add the generated heap dump to | 34 [`ExportHeapDump()`][export-heap-dump], and add the generated heap dump to |
| 35 the memory dump. | 35 the memory dump. |
| 36 | 36 |
| 37 [context-tracker]: https://chromium.googlesource.com/chromium/src/+/master/base
/trace_event/heap_profiler_allocation_context_tracker.h | 37 [context-tracker]: https://chromium.googlesource.com/chromium/src/+/master/base
/trace_event/heap_profiler_allocation_context_tracker.h |
| 38 [alloc-context]: https://chromium.googlesource.com/chromium/src/+/master/base
/trace_event/heap_profiler_allocation_context.h | 38 [alloc-context]: https://chromium.googlesource.com/chromium/src/+/master/base
/trace_event/heap_profiler_allocation_context.h |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 | 114 |
| 115 // Kept as pointer because |AllocationRegister| allocates a lot of virtual | 115 // Kept as pointer because |AllocationRegister| allocates a lot of virtual |
| 116 // address space when constructed, so only construct it when heap profiling is | 116 // address space when constructed, so only construct it when heap profiling is |
| 117 // enabled. | 117 // enabled. |
| 118 scoped_ptr<AllocationRegister> allocation_register_; | 118 scoped_ptr<AllocationRegister> allocation_register_; |
| 119 Lock allocation_register_lock_; | 119 Lock allocation_register_lock_; |
| 120 | 120 |
| 121 static FooDumpProvider* GetInstance(); | 121 static FooDumpProvider* GetInstance(); |
| 122 | 122 |
| 123 void InsertAllocation(void* address, size_t size) { | 123 void InsertAllocation(void* address, size_t size) { |
| 124 AllocationContext context = AllocationContextTracker::GetInstanceForCurrentT
hread()->GetContextSnapshot(); | 124 AllocationContext context = AllocationContextTracker::GetContextSnapshot(); |
| 125 AutoLock lock(allocation_register_lock_); | 125 AutoLock lock(allocation_register_lock_); |
| 126 allocation_register_->Insert(address, size, context); | 126 allocation_register_->Insert(address, size, context); |
| 127 } | 127 } |
| 128 | 128 |
| 129 void RemoveAllocation(void* address) { | 129 void RemoveAllocation(void* address) { |
| 130 AutoLock lock(allocation_register_lock_); | 130 AutoLock lock(allocation_register_lock_); |
| 131 allocation_register_->Remove(address); | 131 allocation_register_->Remove(address); |
| 132 } | 132 } |
| 133 | 133 |
| 134 // Will be called as early as possible by the memory dump manager. | 134 // Will be called as early as possible by the memory dump manager. |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 return true; | 175 return true; |
| 176 } | 176 } |
| 177 }; | 177 }; |
| 178 | 178 |
| 179 ``` | 179 ``` |
| 180 | 180 |
| 181 *** aside | 181 *** aside |
| 182 The implementation for `malloc` is more complicated because it needs to deal | 182 The implementation for `malloc` is more complicated because it needs to deal |
| 183 with reentrancy. | 183 with reentrancy. |
| 184 *** | 184 *** |
| OLD | NEW |