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 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 | 360 |
361 size_t InvalidGetAllocatedSize(void* ptr) { | 361 size_t InvalidGetAllocatedSize(void* ptr) { |
362 CRASH("Attempt to get the size of an invalid pointer: %p\n", ptr); | 362 CRASH("Attempt to get the size of an invalid pointer: %p\n", ptr); |
363 return 0; | 363 return 0; |
364 } | 364 } |
365 } // unnamed namespace | 365 } // unnamed namespace |
366 | 366 |
367 // Extract interesting stats | 367 // Extract interesting stats |
368 struct TCMallocStats { | 368 struct TCMallocStats { |
369 uint64_t system_bytes; // Bytes alloced from system | 369 uint64_t system_bytes; // Bytes alloced from system |
| 370 uint64_t committed_bytes; // Bytes alloced and committed from system |
370 uint64_t thread_bytes; // Bytes in thread caches | 371 uint64_t thread_bytes; // Bytes in thread caches |
371 uint64_t central_bytes; // Bytes in central cache | 372 uint64_t central_bytes; // Bytes in central cache |
372 uint64_t transfer_bytes; // Bytes in central transfer cache | 373 uint64_t transfer_bytes; // Bytes in central transfer cache |
373 uint64_t pageheap_bytes; // Bytes in page heap | 374 uint64_t pageheap_bytes; // Bytes in page heap |
374 uint64_t metadata_bytes; // Bytes alloced for metadata | 375 uint64_t metadata_bytes; // Bytes alloced for metadata |
375 }; | 376 }; |
376 | 377 |
377 // Get stats into "r". Also get per-size-class counts if class_count != NULL | 378 // Get stats into "r". Also get per-size-class counts if class_count != NULL |
378 static void ExtractStats(TCMallocStats* r, uint64_t* class_count) { | 379 static void ExtractStats(TCMallocStats* r, uint64_t* class_count) { |
379 r->central_bytes = 0; | 380 r->central_bytes = 0; |
(...skipping 11 matching lines...) Expand all Loading... |
391 // Add stats from per-thread heaps | 392 // Add stats from per-thread heaps |
392 r->thread_bytes = 0; | 393 r->thread_bytes = 0; |
393 { // scope | 394 { // scope |
394 SpinLockHolder h(Static::pageheap_lock()); | 395 SpinLockHolder h(Static::pageheap_lock()); |
395 ThreadCache::GetThreadStats(&r->thread_bytes, class_count); | 396 ThreadCache::GetThreadStats(&r->thread_bytes, class_count); |
396 } | 397 } |
397 | 398 |
398 { //scope | 399 { //scope |
399 SpinLockHolder h(Static::pageheap_lock()); | 400 SpinLockHolder h(Static::pageheap_lock()); |
400 r->system_bytes = Static::pageheap()->SystemBytes(); | 401 r->system_bytes = Static::pageheap()->SystemBytes(); |
| 402 r->committed_bytes = Static::pageheap()->CommittedBytes(); |
401 r->metadata_bytes = tcmalloc::metadata_system_bytes(); | 403 r->metadata_bytes = tcmalloc::metadata_system_bytes(); |
402 r->pageheap_bytes = Static::pageheap()->FreeBytes(); | 404 r->pageheap_bytes = Static::pageheap()->FreeBytes(); |
403 } | 405 } |
404 } | 406 } |
405 | 407 |
406 // WRITE stats to "out" | 408 // WRITE stats to "out" |
407 static void DumpStats(TCMalloc_Printer* out, int level) { | 409 static void DumpStats(TCMalloc_Printer* out, int level) { |
408 TCMallocStats stats; | 410 TCMallocStats stats; |
409 uint64_t class_count[kNumClasses]; | 411 uint64_t class_count[kNumClasses]; |
410 ExtractStats(&stats, (level >= 2 ? class_count : NULL)); | 412 ExtractStats(&stats, (level >= 2 ? class_count : NULL)); |
411 | 413 |
412 static const double MB = 1048576.0; | 414 static const double MB = 1048576.0; |
413 | 415 |
| 416 const uint64_t bytes_in_use = stats.system_bytes |
| 417 - stats.pageheap_bytes |
| 418 - stats.central_bytes |
| 419 - stats.transfer_bytes |
| 420 - stats.thread_bytes; |
| 421 |
| 422 out->printf("WASTE: %7.1f MB committed but not used\n" |
| 423 "WASTE: %7.1f MB bytes committed, %7.1f MB bytes in use\n" |
| 424 "WASTE: committed/used ratio of %f\n", |
| 425 (stats.committed_bytes - bytes_in_use) / MB, |
| 426 stats.committed_bytes / MB, |
| 427 bytes_in_use / MB, |
| 428 stats.committed_bytes / static_cast<double>(bytes_in_use)); |
| 429 |
414 if (level >= 2) { | 430 if (level >= 2) { |
415 out->printf("------------------------------------------------\n"); | 431 out->printf("------------------------------------------------\n"); |
416 uint64_t cumulative = 0; | 432 uint64_t cumulative = 0; |
417 for (int cl = 0; cl < kNumClasses; ++cl) { | 433 for (int cl = 0; cl < kNumClasses; ++cl) { |
418 if (class_count[cl] > 0) { | 434 if (class_count[cl] > 0) { |
419 uint64_t class_bytes = | 435 uint64_t class_bytes = |
420 class_count[cl] * Static::sizemap()->ByteSizeForClass(cl); | 436 class_count[cl] * Static::sizemap()->ByteSizeForClass(cl); |
421 cumulative += class_bytes; | 437 cumulative += class_bytes; |
422 out->printf("class %3d [ %8" PRIuS " bytes ] : " | 438 out->printf("class %3d [ %8" PRIuS " bytes ] : " |
423 "%8" PRIu64 " objs; %5.1f MB; %5.1f cum MB\n", | 439 "%8" PRIu64 " objs; %5.1f MB; %5.1f cum MB\n", |
424 cl, Static::sizemap()->ByteSizeForClass(cl), | 440 cl, Static::sizemap()->ByteSizeForClass(cl), |
425 class_count[cl], | 441 class_count[cl], |
426 class_bytes / MB, | 442 class_bytes / MB, |
427 cumulative / MB); | 443 cumulative / MB); |
428 } | 444 } |
429 } | 445 } |
430 | 446 |
431 SpinLockHolder h(Static::pageheap_lock()); | 447 SpinLockHolder h(Static::pageheap_lock()); |
432 Static::pageheap()->Dump(out); | 448 Static::pageheap()->Dump(out); |
433 | 449 |
434 out->printf("------------------------------------------------\n"); | 450 out->printf("------------------------------------------------\n"); |
435 DumpSystemAllocatorStats(out); | 451 DumpSystemAllocatorStats(out); |
436 } | 452 } |
437 | 453 |
438 const uint64_t bytes_in_use = stats.system_bytes | |
439 - stats.pageheap_bytes | |
440 - stats.central_bytes | |
441 - stats.transfer_bytes | |
442 - stats.thread_bytes; | |
443 | |
444 out->printf("------------------------------------------------\n" | 454 out->printf("------------------------------------------------\n" |
445 "MALLOC: %12" PRIu64 " (%7.1f MB) Heap size\n" | 455 "MALLOC: %12" PRIu64 " (%7.1f MB) Heap size\n" |
| 456 "MALLOC: %12" PRIu64 " (%7.1f MB) Bytes committed\n" |
446 "MALLOC: %12" PRIu64 " (%7.1f MB) Bytes in use by application\n" | 457 "MALLOC: %12" PRIu64 " (%7.1f MB) Bytes in use by application\n" |
447 "MALLOC: %12" PRIu64 " (%7.1f MB) Bytes free in page heap\n" | 458 "MALLOC: %12" PRIu64 " (%7.1f MB) Bytes free in page heap\n" |
448 "MALLOC: %12" PRIu64 " (%7.1f MB) Bytes free in central cache\n" | 459 "MALLOC: %12" PRIu64 " (%7.1f MB) Bytes free in central cache\n" |
449 "MALLOC: %12" PRIu64 " (%7.1f MB) Bytes free in transfer cache\n" | 460 "MALLOC: %12" PRIu64 " (%7.1f MB) Bytes free in transfer cache\n" |
450 "MALLOC: %12" PRIu64 " (%7.1f MB) Bytes free in thread caches\n" | 461 "MALLOC: %12" PRIu64 " (%7.1f MB) Bytes free in thread caches\n" |
451 "MALLOC: %12" PRIu64 " Spans in use\n" | 462 "MALLOC: %12" PRIu64 " Spans in use\n" |
452 "MALLOC: %12" PRIu64 " Thread heaps in use\n" | 463 "MALLOC: %12" PRIu64 " Thread heaps in use\n" |
453 "MALLOC: %12" PRIu64 " (%7.1f MB) Metadata allocated\n" | 464 "MALLOC: %12" PRIu64 " (%7.1f MB) Metadata allocated\n" |
454 "------------------------------------------------\n", | 465 "------------------------------------------------\n", |
455 stats.system_bytes, stats.system_bytes / MB, | 466 stats.system_bytes, stats.system_bytes / MB, |
| 467 stats.committed_bytes, stats.committed_bytes / MB, |
456 bytes_in_use, bytes_in_use / MB, | 468 bytes_in_use, bytes_in_use / MB, |
457 stats.pageheap_bytes, stats.pageheap_bytes / MB, | 469 stats.pageheap_bytes, stats.pageheap_bytes / MB, |
458 stats.central_bytes, stats.central_bytes / MB, | 470 stats.central_bytes, stats.central_bytes / MB, |
459 stats.transfer_bytes, stats.transfer_bytes / MB, | 471 stats.transfer_bytes, stats.transfer_bytes / MB, |
460 stats.thread_bytes, stats.thread_bytes / MB, | 472 stats.thread_bytes, stats.thread_bytes / MB, |
461 uint64_t(Static::span_allocator()->inuse()), | 473 uint64_t(Static::span_allocator()->inuse()), |
462 uint64_t(ThreadCache::HeapsInUse()), | 474 uint64_t(ThreadCache::HeapsInUse()), |
463 stats.metadata_bytes, stats.metadata_bytes / MB); | 475 stats.metadata_bytes, stats.metadata_bytes / MB); |
464 } | 476 } |
465 | 477 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
564 return true; | 576 return true; |
565 } | 577 } |
566 | 578 |
567 if (strcmp(name, "generic.heap_size") == 0) { | 579 if (strcmp(name, "generic.heap_size") == 0) { |
568 TCMallocStats stats; | 580 TCMallocStats stats; |
569 ExtractStats(&stats, NULL); | 581 ExtractStats(&stats, NULL); |
570 *value = stats.system_bytes; | 582 *value = stats.system_bytes; |
571 return true; | 583 return true; |
572 } | 584 } |
573 | 585 |
| 586 if (strcmp(name, "generic.committed_bytes") == 0) { |
| 587 TCMallocStats stats; |
| 588 ExtractStats(&stats, NULL); |
| 589 *value = Static::pageheap()->CommittedBytes(); |
| 590 return true; |
| 591 } |
| 592 |
574 if (strcmp(name, "tcmalloc.slack_bytes") == 0) { | 593 if (strcmp(name, "tcmalloc.slack_bytes") == 0) { |
575 // We assume that bytes in the page heap are not fragmented too | 594 // We assume that bytes in the page heap are not fragmented too |
576 // badly, and are therefore available for allocation. | 595 // badly, and are therefore available for allocation. |
577 SpinLockHolder l(Static::pageheap_lock()); | 596 SpinLockHolder l(Static::pageheap_lock()); |
578 *value = Static::pageheap()->FreeBytes(); | 597 *value = Static::pageheap()->FreeBytes(); |
579 return true; | 598 return true; |
580 } | 599 } |
581 | 600 |
582 if (strcmp(name, "tcmalloc.max_total_thread_cache_bytes") == 0) { | 601 if (strcmp(name, "tcmalloc.max_total_thread_cache_bytes") == 0) { |
583 SpinLockHolder l(Static::pageheap_lock()); | 602 SpinLockHolder l(Static::pageheap_lock()); |
(...skipping 700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1284 static void *MemalignOverride(size_t align, size_t size, const void *caller) | 1303 static void *MemalignOverride(size_t align, size_t size, const void *caller) |
1285 __THROW ATTRIBUTE_SECTION(google_malloc); | 1304 __THROW ATTRIBUTE_SECTION(google_malloc); |
1286 | 1305 |
1287 static void *MemalignOverride(size_t align, size_t size, const void *caller) | 1306 static void *MemalignOverride(size_t align, size_t size, const void *caller) |
1288 __THROW { | 1307 __THROW { |
1289 void* result = do_memalign(align, size); | 1308 void* result = do_memalign(align, size); |
1290 MallocHook::InvokeNewHook(result, size); | 1309 MallocHook::InvokeNewHook(result, size); |
1291 return result; | 1310 return result; |
1292 } | 1311 } |
1293 void *(*__memalign_hook)(size_t, size_t, const void *) = MemalignOverride; | 1312 void *(*__memalign_hook)(size_t, size_t, const void *) = MemalignOverride; |
OLD | NEW |