Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(313)

Side by Side Diff: base/trace_event/malloc_dump_provider.cc

Issue 2350423003: [Tentaive patch for discussion] Add Purge+Suspend metrics as UMA.
Patch Set: Add v8 heap usage Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/trace_event/malloc_dump_provider.h" 5 #include "base/trace_event/malloc_dump_provider.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include "base/allocator/allocator_extension.h" 9 #include "base/allocator/allocator_extension.h"
10 #include "base/allocator/allocator_shim.h" 10 #include "base/allocator/allocator_shim.h"
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 MallocDumpProvider* MallocDumpProvider::GetInstance() { 182 MallocDumpProvider* MallocDumpProvider::GetInstance() {
183 return Singleton<MallocDumpProvider, 183 return Singleton<MallocDumpProvider,
184 LeakySingletonTraits<MallocDumpProvider>>::get(); 184 LeakySingletonTraits<MallocDumpProvider>>::get();
185 } 185 }
186 186
187 MallocDumpProvider::MallocDumpProvider() 187 MallocDumpProvider::MallocDumpProvider()
188 : heap_profiler_enabled_(false), tid_dumping_heap_(kInvalidThreadId) {} 188 : heap_profiler_enabled_(false), tid_dumping_heap_(kInvalidThreadId) {}
189 189
190 MallocDumpProvider::~MallocDumpProvider() {} 190 MallocDumpProvider::~MallocDumpProvider() {}
191 191
192 // Called at trace dump point time. Creates a snapshot the memory counters for 192 MallocStatistics MallocDumpProvider::GetStatistics() {
193 // the current process. 193 MallocStatistics stats;
194 bool MallocDumpProvider::OnMemoryDump(const MemoryDumpArgs& args, 194
195 ProcessMemoryDump* pmd) {
196 size_t total_virtual_size = 0;
197 size_t resident_size = 0;
198 size_t allocated_objects_size = 0;
199 size_t allocated_objects_count = 0;
200 #if defined(USE_TCMALLOC) 195 #if defined(USE_TCMALLOC)
201 bool res = 196 bool res = allocator::GetNumericProperty("generic.heap_size",
202 allocator::GetNumericProperty("generic.heap_size", &total_virtual_size); 197 &stats.total_virtual_size);
203 DCHECK(res); 198 DCHECK(res);
204 res = allocator::GetNumericProperty("generic.total_physical_bytes", 199 res = allocator::GetNumericProperty("generic.total_physical_bytes",
205 &resident_size); 200 &stats.resident_size);
206 DCHECK(res); 201 DCHECK(res);
207 res = allocator::GetNumericProperty("generic.current_allocated_bytes", 202 res = allocator::GetNumericProperty("generic.current_allocated_bytes",
208 &allocated_objects_size); 203 &stats.allocated_objects_size);
209 DCHECK(res); 204 DCHECK(res);
210 #elif defined(OS_MACOSX) || defined(OS_IOS) 205 #elif defined(OS_MACOSX) || defined(OS_IOS)
211 malloc_statistics_t stats = {0}; 206 malloc_statistics_t stats = {0};
212 malloc_zone_statistics(nullptr, &stats); 207 malloc_zone_statistics(nullptr, &stats);
213 total_virtual_size = stats.size_allocated; 208 stats.total_virtual_size = stats.size_allocated;
214 allocated_objects_size = stats.size_in_use; 209 stats.allocated_objects_size = stats.size_in_use;
215 210
216 // The resident size is approximated to the max size in use, which would count 211 // The resident size is approximated to the max size in use, which would count
217 // the total size of all regions other than the free bytes at the end of each 212 // the total size of all regions other than the free bytes at the end of each
218 // region. In each allocation region the allocations are rounded off to a 213 // region. In each allocation region the allocations are rounded off to a
219 // fixed quantum, so the excess region will not be resident. 214 // fixed quantum, so the excess region will not be resident.
220 // See crrev.com/1531463004 for detailed explanation. 215 // See crrev.com/1531463004 for detailed explanation.
221 resident_size = stats.max_size_in_use; 216 stats.resident_size = stats.max_size_in_use;
222 #elif defined(OS_WIN) 217 #elif defined(OS_WIN)
223 WinHeapInfo all_heap_info = {}; 218 WinHeapInfo all_heap_info = {};
224 WinHeapMemoryDumpImpl(&all_heap_info); 219 WinHeapMemoryDumpImpl(&all_heap_info);
225 total_virtual_size = 220 stats.total_virtual_size =
226 all_heap_info.committed_size + all_heap_info.uncommitted_size; 221 all_heap_info.committed_size + all_heap_info.uncommitted_size;
227 // Resident size is approximated with committed heap size. Note that it is 222 // Resident size is approximated with committed heap size. Note that it is
228 // possible to do this with better accuracy on windows by intersecting the 223 // possible to do this with better accuracy on windows by intersecting the
229 // working set with the virtual memory ranges occuipied by the heap. It's not 224 // working set with the virtual memory ranges occuipied by the heap. It's not
230 // clear that this is worth it, as it's fairly expensive to do. 225 // clear that this is worth it, as it's fairly expensive to do.
231 resident_size = all_heap_info.committed_size; 226 stats.resident_size = all_heap_info.committed_size;
232 allocated_objects_size = all_heap_info.allocated_size; 227 stats.allocated_objects_size = all_heap_info.allocated_size;
233 allocated_objects_count = all_heap_info.block_count; 228 stats.allocated_objects_count = all_heap_info.block_count;
234 #else 229 #else
235 struct mallinfo info = mallinfo(); 230 struct mallinfo info = mallinfo();
236 DCHECK_GE(info.arena + info.hblkhd, info.uordblks); 231 DCHECK_GE(info.arena + info.hblkhd, info.uordblks);
237 232
238 // In case of Android's jemalloc |arena| is 0 and the outer pages size is 233 // In case of Android's jemalloc |arena| is 0 and the outer pages size is
239 // reported by |hblkhd|. In case of dlmalloc the total is given by 234 // reported by |hblkhd|. In case of dlmalloc the total is given by
240 // |arena| + |hblkhd|. For more details see link: http://goo.gl/fMR8lF. 235 // |arena| + |hblkhd|. For more details see link: http://goo.gl/fMR8lF.
241 total_virtual_size = info.arena + info.hblkhd; 236 stats.total_virtual_size = info.arena + info.hblkhd;
242 resident_size = info.uordblks; 237 stats.resident_size = info.uordblks;
243 238
244 // Total allocated space is given by |uordblks|. 239 // Total allocated space is given by |uordblks|.
245 allocated_objects_size = info.uordblks; 240 stats.allocated_objects_size = info.uordblks;
246 #endif 241 #endif
242 if (stats.resident_size > stats.allocated_objects_size) {
243 // Explicitly specify why is extra memory resident. In tcmalloc it accounts
244 // for free lists and caches. In mac and ios it accounts for the
245 // fragmentation and metadata.
246 stats.allocated_objects_size =
247 stats.resident_size - stats.allocated_objects_size;
248 }
249 return stats;
250 }
251
252 // Called at trace dump point time. Creates a snapshot the memory counters for
253 // the current process.
254 bool MallocDumpProvider::OnMemoryDump(const MemoryDumpArgs& args,
255 ProcessMemoryDump* pmd) {
256 MallocStatistics stats = GetStatistics();
247 257
248 MemoryAllocatorDump* outer_dump = pmd->CreateAllocatorDump("malloc"); 258 MemoryAllocatorDump* outer_dump = pmd->CreateAllocatorDump("malloc");
249 outer_dump->AddScalar("virtual_size", MemoryAllocatorDump::kUnitsBytes, 259 outer_dump->AddScalar("virtual_size", MemoryAllocatorDump::kUnitsBytes,
250 total_virtual_size); 260 stats.total_virtual_size);
251 outer_dump->AddScalar(MemoryAllocatorDump::kNameSize, 261 outer_dump->AddScalar(MemoryAllocatorDump::kNameSize,
252 MemoryAllocatorDump::kUnitsBytes, resident_size); 262 MemoryAllocatorDump::kUnitsBytes, stats.resident_size);
253 263
254 MemoryAllocatorDump* inner_dump = pmd->CreateAllocatorDump(kAllocatedObjects); 264 MemoryAllocatorDump* inner_dump = pmd->CreateAllocatorDump(kAllocatedObjects);
255 inner_dump->AddScalar(MemoryAllocatorDump::kNameSize, 265 inner_dump->AddScalar(MemoryAllocatorDump::kNameSize,
256 MemoryAllocatorDump::kUnitsBytes, 266 MemoryAllocatorDump::kUnitsBytes,
257 allocated_objects_size); 267 stats.allocated_objects_size);
258 if (allocated_objects_count != 0) { 268 if (stats.allocated_objects_count != 0) {
259 inner_dump->AddScalar(MemoryAllocatorDump::kNameObjectCount, 269 inner_dump->AddScalar(MemoryAllocatorDump::kNameObjectCount,
260 MemoryAllocatorDump::kUnitsObjects, 270 MemoryAllocatorDump::kUnitsObjects,
261 allocated_objects_count); 271 stats.allocated_objects_count);
262 } 272 }
263 273
264 if (resident_size > allocated_objects_size) { 274 if (stats.metadata_fragmentation_caches > 0) {
265 // Explicitly specify why is extra memory resident. In tcmalloc it accounts 275 // Explicitly specify why is extra memory resident. In tcmalloc it accounts
266 // for free lists and caches. In mac and ios it accounts for the 276 // for free lists and caches. In mac and ios it accounts for the
267 // fragmentation and metadata. 277 // fragmentation and metadata.
268 MemoryAllocatorDump* other_dump = 278 MemoryAllocatorDump* other_dump =
269 pmd->CreateAllocatorDump("malloc/metadata_fragmentation_caches"); 279 pmd->CreateAllocatorDump("malloc/metadata_fragmentation_caches");
270 other_dump->AddScalar(MemoryAllocatorDump::kNameSize, 280 other_dump->AddScalar(MemoryAllocatorDump::kNameSize,
271 MemoryAllocatorDump::kUnitsBytes, 281 MemoryAllocatorDump::kUnitsBytes,
272 resident_size - allocated_objects_size); 282 stats.metadata_fragmentation_caches);
273 } 283 }
274 284
275 // Heap profiler dumps. 285 // Heap profiler dumps.
276 if (!heap_profiler_enabled_) 286 if (!heap_profiler_enabled_)
277 return true; 287 return true;
278 288
279 // The dumps of the heap profiler should be created only when heap profiling 289 // The dumps of the heap profiler should be created only when heap profiling
280 // was enabled (--enable-heap-profiling) AND a DETAILED dump is requested. 290 // was enabled (--enable-heap-profiling) AND a DETAILED dump is requested.
281 // However, when enabled, the overhead of the heap profiler should be always 291 // However, when enabled, the overhead of the heap profiler should be always
282 // reported to avoid oscillations of the malloc total in LIGHT dumps. 292 // reported to avoid oscillations of the malloc total in LIGHT dumps.
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 tid_dumping_heap_ == PlatformThread::CurrentId()) 367 tid_dumping_heap_ == PlatformThread::CurrentId())
358 return; 368 return;
359 AutoLock lock(allocation_register_lock_); 369 AutoLock lock(allocation_register_lock_);
360 if (!allocation_register_) 370 if (!allocation_register_)
361 return; 371 return;
362 allocation_register_->Remove(address); 372 allocation_register_->Remove(address);
363 } 373 }
364 374
365 } // namespace trace_event 375 } // namespace trace_event
366 } // namespace base 376 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698