0

Emit global handles size in memory dump and add UKM/UMA metrics

Add accounting for global handles in memory dumps. Add UKM/UMA
metrics for them as well to help uncover regressions and get some
statistics.

Privacy review doc: https://goo.gl/X5eYHh

New metric: Memory.Experimental.Renderer2.V8.Main.GlobalHandles

Change-Id: I5fba506fe9ce7f8b676f676f10f52f81f7a62639
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2084594
Reviewed-by: ssid <ssid@chromium.org>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: Robert Kaplow <rkaplow@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#748388}
This commit is contained in:
Dominik Inführ
2020-03-09 21:32:56 +00:00
committed by Commit Bot
parent 0aa7ca7cf8
commit e35b641ca4
7 changed files with 76 additions and 34 deletions

@ -283,6 +283,7 @@ const char* const kAllocatorDumpNameWhitelist[] = {
"v8/main/code_stats", "v8/main/code_stats",
"v8/main/contexts/detached_context", "v8/main/contexts/detached_context",
"v8/main/contexts/native_context", "v8/main/contexts/native_context",
"v8/main/global_handles",
"v8/main/heap/code_space", "v8/main/heap/code_space",
"v8/main/heap/code_stats", "v8/main/heap/code_stats",
"v8/main/heap/code_large_object_space", "v8/main/heap/code_large_object_space",

@ -248,6 +248,9 @@ const Metric kAllocatorDumpNamesForMetrics[] = {
{"v8/main", "V8.Main.AllocatedObjects", MetricSize::kLarge, {"v8/main", "V8.Main.AllocatedObjects", MetricSize::kLarge,
kAllocatedObjectsSize, EmitTo::kSizeInUkmAndUma, kAllocatedObjectsSize, EmitTo::kSizeInUkmAndUma,
&Memory_Experimental::SetV8_Main_AllocatedObjects}, &Memory_Experimental::SetV8_Main_AllocatedObjects},
{"v8/main/global_handles", "V8.Main.GlobalHandles", MetricSize::kSmall,
kEffectiveSize, EmitTo::kSizeInUkmAndUma,
&Memory_Experimental::SetV8_Main_GlobalHandles},
{"v8/main/heap", "V8.Main.Heap", MetricSize::kLarge, kEffectiveSize, {"v8/main/heap", "V8.Main.Heap", MetricSize::kLarge, kEffectiveSize,
EmitTo::kSizeInUkmAndUma, &Memory_Experimental::SetV8_Main_Heap}, EmitTo::kSizeInUkmAndUma, &Memory_Experimental::SetV8_Main_Heap},
{"v8/main/heap", "V8.Main.Heap.AllocatedObjects", MetricSize::kLarge, {"v8/main/heap", "V8.Main.Heap.AllocatedObjects", MetricSize::kLarge,

@ -209,6 +209,9 @@ void PopulateRendererMetrics(GlobalMemoryDumpPtr& global_dump,
SetAllocatorDumpMetric( SetAllocatorDumpMetric(
pmd, "v8/main", "allocated_objects_size", pmd, "v8/main", "allocated_objects_size",
metrics_mb_or_count["V8.Main.AllocatedObjects"] * 1024 * 1024); metrics_mb_or_count["V8.Main.AllocatedObjects"] * 1024 * 1024);
SetAllocatorDumpMetric(
pmd, "v8/main/global_handles", "effective_size",
metrics_mb_or_count["V8.Main.GlobalHandles"] * 1024 * 1024);
SetAllocatorDumpMetric(pmd, "v8/main/heap", "effective_size", SetAllocatorDumpMetric(pmd, "v8/main/heap", "effective_size",
metrics_mb_or_count["V8.Main.Heap"] * 1024 * 1024); metrics_mb_or_count["V8.Main.Heap"] * 1024 * 1024);
@ -341,44 +344,43 @@ constexpr base::ProcessId kTestRendererPid202 = 202;
constexpr base::ProcessId kTestRendererPid203 = 203; constexpr base::ProcessId kTestRendererPid203 = 203;
MetricMap GetExpectedRendererMetrics() { MetricMap GetExpectedRendererMetrics() {
return MetricMap( return MetricMap({
{ {"ProcessType", static_cast<int64_t>(ProcessType::RENDERER)},
{"ProcessType", static_cast<int64_t>(ProcessType::RENDERER)},
#if !defined(OS_MACOSX) #if !defined(OS_MACOSX)
{"Resident", kTestRendererResidentSet}, {"Resident", kTestRendererResidentSet},
#endif #endif
{"Malloc", 120}, {"Malloc", 120},
{"PrivateMemoryFootprint", kTestRendererPrivateMemoryFootprint}, {"PrivateMemoryFootprint", kTestRendererPrivateMemoryFootprint},
{"SharedMemoryFootprint", kTestRendererSharedMemoryFootprint}, {"SharedMemoryFootprint", kTestRendererSharedMemoryFootprint},
{"PartitionAlloc", 140}, {"BlinkGC", 150}, {"V8", 160}, {"PartitionAlloc", 140}, {"BlinkGC", 150}, {"V8", 160},
{"V8.AllocatedObjects", 70}, {"V8.Main", 100}, {"V8.AllocatedObjects", 70}, {"V8.Main", 100},
{"V8.Main.AllocatedObjects", 30}, {"V8.Main.Heap", 98}, {"V8.Main.AllocatedObjects", 30}, {"V8.Main.Heap", 98},
{"V8.Main.Heap.AllocatedObjects", 28}, {"V8.Main.GlobalHandles", 3}, {"V8.Main.Heap.AllocatedObjects", 28},
{"V8.Main.Heap.CodeSpace", 11}, {"V8.Main.Heap.CodeSpace", 11},
{"V8.Main.Heap.CodeSpace.AllocatedObjects", 1}, {"V8.Main.Heap.CodeSpace.AllocatedObjects", 1},
{"V8.Main.Heap.LargeObjectSpace", 12}, {"V8.Main.Heap.LargeObjectSpace", 12},
{"V8.Main.Heap.LargeObjectSpace.AllocatedObjects", 2}, {"V8.Main.Heap.LargeObjectSpace.AllocatedObjects", 2},
{"V8.Main.Heap.MapSpace", 13}, {"V8.Main.Heap.MapSpace", 13},
{"V8.Main.Heap.MapSpace.AllocatedObjects", 3}, {"V8.Main.Heap.MapSpace.AllocatedObjects", 3},
{"V8.Main.Heap.NewLargeObjectSpace", 14}, {"V8.Main.Heap.NewLargeObjectSpace", 14},
{"V8.Main.Heap.NewLargeObjectSpace.AllocatedObjects", 4}, {"V8.Main.Heap.NewLargeObjectSpace.AllocatedObjects", 4},
{"V8.Main.Heap.NewSpace", 15}, {"V8.Main.Heap.NewSpace", 15},
{"V8.Main.Heap.NewSpace.AllocatedObjects", 5}, {"V8.Main.Heap.NewSpace.AllocatedObjects", 5},
{"V8.Main.Heap.OldSpace", 16}, {"V8.Main.Heap.OldSpace", 16},
{"V8.Main.Heap.NewSpace.AllocatedObjects", 6}, {"V8.Main.Heap.NewSpace.AllocatedObjects", 6},
{"V8.Main.Heap.ReadOnlySpace", 17}, {"V8.Main.Heap.ReadOnlySpace", 17},
{"V8.Main.Heap.ReadOnlySpace.AllocatedObjects", 7}, {"V8.Main.Heap.ReadOnlySpace.AllocatedObjects", 7},
{"V8.Main.Malloc", 2}, {"V8.Workers", 60}, {"V8.Main.Malloc", 2}, {"V8.Workers", 60},
{"V8.Workers.AllocatedObjects", 40}, {"NumberOfExtensions", 0}, {"V8.Workers.AllocatedObjects", 40}, {"NumberOfExtensions", 0},
{"Uptime", 42}, {"Uptime", 42},
#if defined(OS_LINUX) || defined(OS_ANDROID) #if defined(OS_LINUX) || defined(OS_ANDROID)
{"PrivateSwapFootprint", 50}, {"PrivateSwapFootprint", 50},
#endif #endif
{"NumberOfAdSubframes", 28}, {"NumberOfDetachedScriptStates", 11}, {"NumberOfAdSubframes", 28}, {"NumberOfDetachedScriptStates", 11},
{"NumberOfDocuments", 1}, {"NumberOfFrames", 2}, {"NumberOfDocuments", 1}, {"NumberOfFrames", 2},
{"NumberOfLayoutObjects", 5}, {"NumberOfNodes", 3}, {"NumberOfLayoutObjects", 5}, {"NumberOfNodes", 3},
{"PartitionAlloc.Partitions.ArrayBuffer", 10}, {"PartitionAlloc.Partitions.ArrayBuffer", 10},
}); });
} }
void AddPageMetrics(MetricMap& expected_metrics) { void AddPageMetrics(MetricMap& expected_metrics) {

@ -253,6 +253,14 @@ void V8IsolateMemoryDumpProvider::DumpHeapStatistics(
// Dump statistics related to code and bytecode if requested. // Dump statistics related to code and bytecode if requested.
DumpCodeStatistics(code_stats_dump, isolate_holder_); DumpCodeStatistics(code_stats_dump, isolate_holder_);
// Dump statistics for global handles.
auto* global_handles_dump = process_memory_dump->CreateAllocatorDump(
dump_base_name + "/global_handles" + dump_name_suffix);
global_handles_dump->AddScalar(
base::trace_event::MemoryAllocatorDump::kNameSize,
base::trace_event::MemoryAllocatorDump::kUnitsBytes,
heap_statistics.total_global_handles_size());
// Dump object statistics only for detailed dumps. // Dump object statistics only for detailed dumps.
if (args.level_of_detail != if (args.level_of_detail !=
base::trace_event::MemoryDumpLevelOfDetail::DETAILED) { base::trace_event::MemoryDumpLevelOfDetail::DETAILED) {

@ -64,6 +64,27 @@ TEST_F(V8MemoryDumpProviderTest, DumpStatistics) {
ASSERT_TRUE(did_dump_objects_stats); ASSERT_TRUE(did_dump_objects_stats);
} }
TEST_F(V8MemoryDumpProviderTest, DumpGlobalHandlesSize) {
base::trace_event::MemoryDumpArgs dump_args = {
base::trace_event::MemoryDumpLevelOfDetail::BACKGROUND};
std::unique_ptr<base::trace_event::ProcessMemoryDump> process_memory_dump(
new base::trace_event::ProcessMemoryDump(dump_args));
instance_->isolate_memory_dump_provider_for_testing()->OnMemoryDump(
dump_args, process_memory_dump.get());
const base::trace_event::ProcessMemoryDump::AllocatorDumpsMap&
allocator_dumps = process_memory_dump->allocator_dumps();
bool did_dump_global_handles = false;
for (const auto& name_dump : allocator_dumps) {
const std::string& name = name_dump.first;
if (name.find("v8/main/global_handles") != std::string::npos) {
did_dump_global_handles = true;
}
}
ASSERT_TRUE(did_dump_global_handles);
}
TEST_F(V8MemoryDumpProviderTest, DumpContextStatistics) { TEST_F(V8MemoryDumpProviderTest, DumpContextStatistics) {
base::trace_event::MemoryDumpArgs dump_args = { base::trace_event::MemoryDumpArgs dump_args = {
base::trace_event::MemoryDumpLevelOfDetail::LIGHT}; base::trace_event::MemoryDumpLevelOfDetail::LIGHT};

@ -193377,6 +193377,8 @@ regressions. -->
<suffix name="V8" label="Only counting memory used by V8 javascript engine."/> <suffix name="V8" label="Only counting memory used by V8 javascript engine."/>
<suffix name="V8.AllocatedObjects" <suffix name="V8.AllocatedObjects"
label="Only counting objects allocated by V8 javascript engine."/> label="Only counting objects allocated by V8 javascript engine."/>
<suffix name="V8.Main.GlobalHandles"
label="Memory used by V8 global handles in the main isolate."/>
<affected-histogram name="Memory.Experimental.Browser2"/> <affected-histogram name="Memory.Experimental.Browser2"/>
<affected-histogram name="Memory.Experimental.Extension2"/> <affected-histogram name="Memory.Experimental.Extension2"/>
<affected-histogram name="Memory.Experimental.Gpu2"/> <affected-histogram name="Memory.Experimental.Gpu2"/>

@ -6079,6 +6079,11 @@ be describing additional metrics about the same event.
Measure of memory consumed by live objects in the main isolate of V8. Measure of memory consumed by live objects in the main isolate of V8.
</summary> </summary>
</metric> </metric>
<metric name="V8.Main.GlobalHandles">
<summary>
Measure of memory consumed by global handles in V8.
</summary>
</metric>
<metric name="V8.Main.Heap"> <metric name="V8.Main.Heap">
<summary> <summary>
Measure of memory consumed by the main heap of V8. Measure of memory consumed by the main heap of V8.