| Index: base/memory/malloc_statistics.cc
|
| diff --git a/base/memory/malloc_statistics.cc b/base/memory/malloc_statistics.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..ab5a20e0431aebabc777ca735a8bebfc576d0177
|
| --- /dev/null
|
| +++ b/base/memory/malloc_statistics.cc
|
| @@ -0,0 +1,83 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "base/memory/malloc_statistics.h"
|
| +
|
| +#include "base/allocator/allocator_extension.h"
|
| +#include "base/logging.h"
|
| +
|
| +#if defined(OS_MACOSX)
|
| +#include <malloc/malloc.h>
|
| +#else
|
| +#include <malloc.h>
|
| +#endif
|
| +#if defined(OS_WIN)
|
| +#include <windows.h>
|
| +#endif
|
| +
|
| +namespace base {
|
| +namespace memory {
|
| +
|
| +MallocStatistics MallocStatistics::GetStatistics() {
|
| + MallocStatistics malloc_stats;
|
| +
|
| +#if defined(USE_TCMALLOC)
|
| + bool res = allocator::GetNumericProperty("generic.heap_size",
|
| + &malloc_stats.total_virtual_size);
|
| + DCHECK(res);
|
| + res = allocator::GetNumericProperty("generic.total_physical_bytes",
|
| + &malloc_stats.resident_size);
|
| + DCHECK(res);
|
| + res = allocator::GetNumericProperty("generic.current_allocated_bytes",
|
| + &malloc_stats.allocated_objects_size);
|
| + DCHECK(res);
|
| +#elif defined(OS_MACOSX) || defined(OS_IOS)
|
| + malloc_statistics_t stats = {0};
|
| + malloc_zone_statistics(nullptr, &stats);
|
| + malloc_stats.total_virtual_size = stats.size_allocated;
|
| + malloc_stats.allocated_objects_size = stats.size_in_use;
|
| +
|
| + // The resident size is approximated to the max size in use, which would count
|
| + // the total size of all regions other than the free bytes at the end of each
|
| + // region. In each allocation region the allocations are rounded off to a
|
| + // fixed quantum, so the excess region will not be resident.
|
| + // See crrev.com/1531463004 for detailed explanation.
|
| + malloc_stats.resident_size = stats.max_size_in_use;
|
| +#elif defined(OS_WIN)
|
| + WinHeapInfo all_heap_info = {};
|
| + WinHeapMemoryDumpImpl(&all_heap_info);
|
| + malloc_stats.total_virtual_size =
|
| + all_heap_info.committed_size + all_heap_info.uncommitted_size;
|
| + // Resident size is approximated with committed heap size. Note that it is
|
| + // possible to do this with better accuracy on windows by intersecting the
|
| + // working set with the virtual memory ranges occuipied by the heap. It's not
|
| + // clear that this is worth it, as it's fairly expensive to do.
|
| + malloc_stats.resident_size = all_heap_info.committed_size;
|
| + malloc_stats.allocated_objects_size = all_heap_info.allocated_size;
|
| + malloc_stats.allocated_objects_count = all_heap_info.block_count;
|
| +#else
|
| + struct mallinfo info = mallinfo();
|
| + DCHECK_GE(info.arena + info.hblkhd, info.uordblks);
|
| +
|
| + // In case of Android's jemalloc |arena| is 0 and the outer pages size is
|
| + // reported by |hblkhd|. In case of dlmalloc the total is given by
|
| + // |arena| + |hblkhd|. For more details see link: http://goo.gl/fMR8lF.
|
| + malloc_stats.total_virtual_size = info.arena + info.hblkhd;
|
| + malloc_stats.resident_size = info.uordblks;
|
| +
|
| + // Total allocated space is given by |uordblks|.
|
| + malloc_stats.allocated_objects_size = info.uordblks;
|
| +#endif
|
| + if (malloc_stats.resident_size > malloc_stats.allocated_objects_size) {
|
| + // Explicitly specify why is extra memory resident. In tcmalloc it accounts
|
| + // for free lists and caches. In mac and ios it accounts for the
|
| + // fragmentation and metadata.
|
| + malloc_stats.allocated_objects_size =
|
| + malloc_stats.resident_size - malloc_stats.allocated_objects_size;
|
| + }
|
| + return malloc_stats;
|
| +}
|
| +
|
| +} // namespace trace_event
|
| +} // namespace base
|
|
|