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::GetContextSnapshot()`][context-tracker] | 28 [`AllocationContextTracker::GetInstanceForCurrentThread()->GetContextSnapsho
t()`][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::GetContextSnapshot(); | 124 AllocationContext context = AllocationContextTracker::GetInstanceForCurrentT
hread()->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 |