Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2005, Google Inc. | 1 // Copyright (c) 2005, Google Inc. |
| 2 // All rights reserved. | 2 // All rights reserved. |
| 3 // | 3 // |
| 4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
| 5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
| 6 // met: | 6 // met: |
| 7 // | 7 // |
| 8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
| 9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
| 10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 309 return 0; | 309 return 0; |
| 310 } | 310 } |
| 311 } // unnamed namespace | 311 } // unnamed namespace |
| 312 | 312 |
| 313 // Extract interesting stats | 313 // Extract interesting stats |
| 314 struct TCMallocStats { | 314 struct TCMallocStats { |
| 315 uint64_t thread_bytes; // Bytes in thread caches | 315 uint64_t thread_bytes; // Bytes in thread caches |
| 316 uint64_t central_bytes; // Bytes in central cache | 316 uint64_t central_bytes; // Bytes in central cache |
| 317 uint64_t transfer_bytes; // Bytes in central transfer cache | 317 uint64_t transfer_bytes; // Bytes in central transfer cache |
| 318 uint64_t metadata_bytes; // Bytes alloced for metadata | 318 uint64_t metadata_bytes; // Bytes alloced for metadata |
| 319 uint64_t metadata_unmapped_bytes; // Address space reserved for metadata | |
| 320 // but is not committed. | |
| 319 PageHeap::Stats pageheap; // Stats from page heap | 321 PageHeap::Stats pageheap; // Stats from page heap |
| 320 }; | 322 }; |
| 321 | 323 |
| 322 // Get stats into "r". Also get per-size-class counts if class_count != NULL | 324 // Get stats into "r". Also get per-size-class counts if class_count != NULL |
| 323 static void ExtractStats(TCMallocStats* r, uint64_t* class_count, | 325 static void ExtractStats(TCMallocStats* r, uint64_t* class_count, |
| 324 PageHeap::SmallSpanStats* small_spans, | 326 PageHeap::SmallSpanStats* small_spans, |
| 325 PageHeap::LargeSpanStats* large_spans) { | 327 PageHeap::LargeSpanStats* large_spans) { |
| 326 r->central_bytes = 0; | 328 r->central_bytes = 0; |
| 327 r->transfer_bytes = 0; | 329 r->transfer_bytes = 0; |
| 328 for (int cl = 0; cl < kNumClasses; ++cl) { | 330 for (int cl = 0; cl < kNumClasses; ++cl) { |
| 329 const int length = Static::central_cache()[cl].length(); | 331 const int length = Static::central_cache()[cl].length(); |
| 330 const int tc_length = Static::central_cache()[cl].tc_length(); | 332 const int tc_length = Static::central_cache()[cl].tc_length(); |
| 331 const size_t cache_overhead = Static::central_cache()[cl].OverheadBytes(); | 333 const size_t cache_overhead = Static::central_cache()[cl].OverheadBytes(); |
| 332 const size_t size = static_cast<uint64_t>( | 334 const size_t size = static_cast<uint64_t>( |
| 333 Static::sizemap()->ByteSizeForClass(cl)); | 335 Static::sizemap()->ByteSizeForClass(cl)); |
| 334 r->central_bytes += (size * length) + cache_overhead; | 336 r->central_bytes += (size * length) + cache_overhead; |
| 335 r->transfer_bytes += (size * tc_length); | 337 r->transfer_bytes += (size * tc_length); |
| 336 if (class_count) class_count[cl] = length + tc_length; | 338 if (class_count) class_count[cl] = length + tc_length; |
| 337 } | 339 } |
| 338 | 340 |
| 339 // Add stats from per-thread heaps | 341 // Add stats from per-thread heaps |
| 340 r->thread_bytes = 0; | 342 r->thread_bytes = 0; |
| 341 { // scope | 343 { // scope |
| 342 SpinLockHolder h(Static::pageheap_lock()); | 344 SpinLockHolder h(Static::pageheap_lock()); |
| 343 ThreadCache::GetThreadStats(&r->thread_bytes, class_count); | 345 ThreadCache::GetThreadStats(&r->thread_bytes, class_count); |
| 344 r->metadata_bytes = tcmalloc::metadata_system_bytes(); | 346 r->metadata_bytes = tcmalloc::metadata_system_bytes(); |
| 347 r->metadata_unmapped_bytes = tcmalloc::metadata_unmapped_bytes(); | |
| 345 r->pageheap = Static::pageheap()->stats(); | 348 r->pageheap = Static::pageheap()->stats(); |
| 346 if (small_spans != NULL) { | 349 if (small_spans != NULL) { |
| 347 Static::pageheap()->GetSmallSpanStats(small_spans); | 350 Static::pageheap()->GetSmallSpanStats(small_spans); |
| 348 } | 351 } |
| 349 if (large_spans != NULL) { | 352 if (large_spans != NULL) { |
| 350 Static::pageheap()->GetLargeSpanStats(large_spans); | 353 Static::pageheap()->GetLargeSpanStats(large_spans); |
| 351 } | 354 } |
| 352 } | 355 } |
| 353 } | 356 } |
| 354 | 357 |
| 355 static double PagesToMiB(uint64_t pages) { | 358 static double PagesToMiB(uint64_t pages) { |
| 356 return (pages << kPageShift) / 1048576.0; | 359 return (pages << kPageShift) / 1048576.0; |
| 357 } | 360 } |
| 358 | 361 |
| 359 // WRITE stats to "out" | 362 // WRITE stats to "out" |
| 360 static void DumpStats(TCMalloc_Printer* out, int level) { | 363 static void DumpStats(TCMalloc_Printer* out, int level) { |
| 361 TCMallocStats stats; | 364 TCMallocStats stats; |
| 362 uint64_t class_count[kNumClasses]; | 365 uint64_t class_count[kNumClasses]; |
| 363 PageHeap::SmallSpanStats small; | 366 PageHeap::SmallSpanStats small; |
| 364 PageHeap::LargeSpanStats large; | 367 PageHeap::LargeSpanStats large; |
| 365 if (level >= 2) { | 368 if (level >= 2) { |
| 366 ExtractStats(&stats, class_count, &small, &large); | 369 ExtractStats(&stats, class_count, &small, &large); |
| 367 } else { | 370 } else { |
| 368 ExtractStats(&stats, NULL, NULL, NULL); | 371 ExtractStats(&stats, NULL, NULL, NULL); |
| 369 } | 372 } |
| 370 | 373 |
| 371 static const double MiB = 1048576.0; | 374 static const double MiB = 1048576.0; |
| 372 | 375 |
| 376 const uint64_t physical_memory_used_by_metadata = | |
| 377 stats.metadata_bytes - stats.metadata_unmapped_bytes; | |
| 378 const uint64_t unmapped_bytes = | |
| 379 stats.pageheap.unmapped_bytes + stats.metadata_unmapped_bytes; | |
| 380 | |
| 373 const uint64_t virtual_memory_used = (stats.pageheap.system_bytes | 381 const uint64_t virtual_memory_used = (stats.pageheap.system_bytes |
| 374 + stats.metadata_bytes); | 382 + stats.metadata_bytes); |
| 375 const uint64_t physical_memory_used = (virtual_memory_used | 383 const uint64_t physical_memory_used = virtual_memory_used - unmapped_bytes; |
| 376 - stats.pageheap.unmapped_bytes); | |
| 377 const uint64_t bytes_in_use_by_app = (physical_memory_used | 384 const uint64_t bytes_in_use_by_app = (physical_memory_used |
| 378 - stats.metadata_bytes | 385 - physical_memory_used_by_metadata |
| 379 - stats.pageheap.free_bytes | 386 - stats.pageheap.free_bytes |
| 380 - stats.central_bytes | 387 - stats.central_bytes |
| 381 - stats.transfer_bytes | 388 - stats.transfer_bytes |
| 382 - stats.thread_bytes); | 389 - stats.thread_bytes); |
| 383 | 390 |
| 384 out->printf( | 391 out->printf( |
| 385 "WASTE: %7.1f MiB committed but not used\n" | 392 "WASTE: %7.1f MiB bytes in use\n" |
| 386 "WASTE: %7.1f MiB bytes committed, %7.1f MiB bytes in use\n" | 393 "WASTE: + %7.1f MiB committed but not used\n" |
| 394 "WASTE: ------------\n" | |
| 395 "WASTE: = %7.1f MiB bytes committed\n" | |
|
jar (doing other things)
2012/06/04 04:31:28
I think I like your formatting better... but does
kaiwang
2012/06/04 18:30:52
This WASTE part(line 391-401) is chromium only, do
| |
| 387 "WASTE: committed/used ratio of %f\n", | 396 "WASTE: committed/used ratio of %f\n", |
| 397 bytes_in_use_by_app / MiB, | |
|
jar (doing other things)
2012/06/04 04:31:28
This probably shouldn't be moved... as it just mak
| |
| 388 (stats.pageheap.committed_bytes - bytes_in_use_by_app) / MiB, | 398 (stats.pageheap.committed_bytes - bytes_in_use_by_app) / MiB, |
| 389 stats.pageheap.committed_bytes / MiB, | 399 stats.pageheap.committed_bytes / MiB, |
| 390 bytes_in_use_by_app / MiB, | |
| 391 stats.pageheap.committed_bytes / static_cast<double>(bytes_in_use_by_app) | 400 stats.pageheap.committed_bytes / static_cast<double>(bytes_in_use_by_app) |
| 392 ); | 401 ); |
| 393 #ifdef TCMALLOC_SMALL_BUT_SLOW | 402 #ifdef TCMALLOC_SMALL_BUT_SLOW |
| 394 out->printf( | 403 out->printf( |
| 395 "NOTE: SMALL MEMORY MODEL IS IN USE, PERFORMANCE MAY SUFFER.\n"); | 404 "NOTE: SMALL MEMORY MODEL IS IN USE, PERFORMANCE MAY SUFFER.\n"); |
| 396 #endif | 405 #endif |
| 397 out->printf( | 406 out->printf( |
| 398 "------------------------------------------------\n" | 407 "------------------------------------------------\n" |
| 399 "MALLOC: %12" PRIu64 " (%7.1f MiB) Bytes in use by application\n" | 408 "MALLOC: %12" PRIu64 " (%7.1f MiB) Bytes in use by application\n" |
| 400 "MALLOC: %12" PRIu64 " (%7.1f MB) Bytes committed\n" | |
| 401 "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes in page heap freelist\n" | 409 "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes in page heap freelist\n" |
| 402 "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes in central cache freelist\n" | 410 "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes in central cache freelist\n" |
| 403 "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes in transfer cache freelist\n" | 411 "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes in transfer cache freelist\n" |
| 404 "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes in thread cache freelists\n" | 412 "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes in thread cache freelists\n" |
| 413 "MALLOC: ------------\n" | |
| 414 "MALLOC: = %12" PRIu64 " (%7.1f MiB) Bytes committed\n" | |
|
jar (doing other things)
2012/06/04 04:31:28
again... I like your format better... but I'd rath
kaiwang
2012/06/04 18:30:52
This single line is actually chromium code (again
| |
| 405 "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes in malloc metadata\n" | 415 "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes in malloc metadata\n" |
| 406 "MALLOC: ------------\n" | 416 "MALLOC: ------------\n" |
| 407 "MALLOC: = %12" PRIu64 " (%7.1f MiB) Actual memory used (physical + swap)\ n" | 417 "MALLOC: = %12" PRIu64 " (%7.1f MiB) Actual memory used (physical + swap)\ n" |
| 408 "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes released to OS (aka unmapped)\n " | 418 "MALLOC: + %12" PRIu64 " (%7.1f MiB) Bytes released to OS (aka unmapped)\n " |
| 409 "MALLOC: ------------\n" | 419 "MALLOC: ------------\n" |
| 410 "MALLOC: = %12" PRIu64 " (%7.1f MiB) Virtual address space used\n" | 420 "MALLOC: = %12" PRIu64 " (%7.1f MiB) Virtual address space used\n" |
| 411 "MALLOC:\n" | 421 "MALLOC:\n" |
| 412 "MALLOC: %12" PRIu64 " Spans in use\n" | 422 "MALLOC: %12" PRIu64 " Spans in use\n" |
| 413 "MALLOC: %12" PRIu64 " Thread heaps in use\n" | 423 "MALLOC: %12" PRIu64 " Thread heaps in use\n" |
| 414 "MALLOC: %12" PRIu64 " Tcmalloc page size\n" | 424 "MALLOC: %12" PRIu64 " Tcmalloc page size\n" |
| 415 "------------------------------------------------\n" | 425 "------------------------------------------------\n" |
| 416 "Call ReleaseFreeMemory() to release freelist memory to the OS" | 426 "Call ReleaseFreeMemory() to release freelist memory to the OS" |
| 417 " (via madvise()).\n" | 427 " (via madvise()).\n" |
| 418 "Bytes released to the OS take up virtual address space" | 428 "Bytes released to the OS take up virtual address space" |
| 419 " but no physical memory.\n", | 429 " but no physical memory.\n", |
| 420 bytes_in_use_by_app, bytes_in_use_by_app / MiB, | 430 bytes_in_use_by_app, bytes_in_use_by_app / MiB, |
| 421 stats.pageheap.committed_bytes, stats.pageheap.committed_bytes / MiB, | |
| 422 stats.pageheap.free_bytes, stats.pageheap.free_bytes / MiB, | 431 stats.pageheap.free_bytes, stats.pageheap.free_bytes / MiB, |
| 423 stats.central_bytes, stats.central_bytes / MiB, | 432 stats.central_bytes, stats.central_bytes / MiB, |
| 424 stats.transfer_bytes, stats.transfer_bytes / MiB, | 433 stats.transfer_bytes, stats.transfer_bytes / MiB, |
| 425 stats.thread_bytes, stats.thread_bytes / MiB, | 434 stats.thread_bytes, stats.thread_bytes / MiB, |
| 426 stats.metadata_bytes, stats.metadata_bytes / MiB, | 435 stats.pageheap.committed_bytes, stats.pageheap.committed_bytes / MiB, |
| 436 physical_memory_used_by_metadata , physical_memory_used_by_metadata / MiB, | |
| 427 physical_memory_used, physical_memory_used / MiB, | 437 physical_memory_used, physical_memory_used / MiB, |
| 428 stats.pageheap.unmapped_bytes, stats.pageheap.unmapped_bytes / MiB, | 438 unmapped_bytes, unmapped_bytes / MiB, |
| 429 virtual_memory_used, virtual_memory_used / MiB, | 439 virtual_memory_used, virtual_memory_used / MiB, |
| 430 uint64_t(Static::span_allocator()->inuse()), | 440 uint64_t(Static::span_allocator()->inuse()), |
| 431 uint64_t(ThreadCache::HeapsInUse()), | 441 uint64_t(ThreadCache::HeapsInUse()), |
| 432 uint64_t(kPageSize)); | 442 uint64_t(kPageSize)); |
| 433 | 443 |
| 434 if (level >= 2) { | 444 if (level >= 2) { |
| 435 out->printf("------------------------------------------------\n"); | 445 out->printf("------------------------------------------------\n"); |
| 436 out->printf("Size class breakdown\n"); | 446 out->printf("Size class breakdown\n"); |
| 437 out->printf("------------------------------------------------\n"); | 447 out->printf("------------------------------------------------\n"); |
| 438 uint64_t cumulative = 0; | 448 uint64_t cumulative = 0; |
| (...skipping 1417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1856 *mark = ~allocated_mark; // Distinctively not allocated. | 1866 *mark = ~allocated_mark; // Distinctively not allocated. |
| 1857 } | 1867 } |
| 1858 | 1868 |
| 1859 static void MarkAllocatedRegion(void* ptr) { | 1869 static void MarkAllocatedRegion(void* ptr) { |
| 1860 if (ptr == NULL) return; | 1870 if (ptr == NULL) return; |
| 1861 MarkType* mark = GetMarkLocation(ptr); | 1871 MarkType* mark = GetMarkLocation(ptr); |
| 1862 *mark = GetMarkValue(ptr, mark); | 1872 *mark = GetMarkValue(ptr, mark); |
| 1863 } | 1873 } |
| 1864 | 1874 |
| 1865 #endif // TCMALLOC_VALIDATION | 1875 #endif // TCMALLOC_VALIDATION |
| OLD | NEW |