Commit b746ecb0 authored by Fadi Meawad's avatar Fadi Meawad Committed by Commit Bot

[Memory UMA] Make memory uma/ukm extension aware

The old memory uma distinguished between extension render process and
non-extension ones. This CL reintroduces that in the new memory UMAs.

For UKM, it add the number of extensions in the process instead.

For both, We only account for true extensions, and we exclude hosted
apps.

Bug: chromium:749775
Change-Id: I5e2dda7d6fa4420af7f63f4cbace09f5f7cf9309
Reviewed-on: https://chromium-review.googlesource.com/611316
Commit-Queue: Fadi Meawad <fmeawad@chromium.org>
Reviewed-by: default avatarSteven Holte <holte@chromium.org>
Reviewed-by: default avatarErik Chen <erikchen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#496583}
parent 95f143fb
......@@ -6,8 +6,12 @@
#include "base/metrics/histogram_macros.h"
#include "base/trace_event/memory_dump_request_args.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/service_manager_connection.h"
#include "content/public/common/service_names.mojom.h"
#include "extensions/features/features.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "services/resource_coordinator/public/cpp/resource_coordinator_features.h"
......@@ -15,6 +19,12 @@
#include "services/service_manager/public/cpp/connector.h"
#include "url/gurl.h"
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/process_map.h"
#include "extensions/common/extension.h"
#endif
using ProcessMemoryDumpPtr =
memory_instrumentation::mojom::ProcessMemoryDumpPtr;
......@@ -44,40 +54,47 @@ void EmitBrowserMemoryMetrics(const ProcessMemoryDumpPtr& pmd,
builder.Record(ukm_recorder);
}
#define RENDERER_MEMORY_UMA_HISTOGRAMS(type) \
do { \
UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Experimental." type "2.Resident", \
pmd->os_dump->resident_set_kb / 1024); \
UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Experimental." type "2.Malloc", \
pmd->chrome_dump->malloc_total_kb / 1024); \
UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Experimental." type \
"2.PrivateMemoryFootprint", \
pmd->os_dump->private_footprint_kb / 1024); \
UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory." type ".PrivateMemoryFootprint", \
pmd->os_dump->private_footprint_kb / 1024); \
UMA_HISTOGRAM_MEMORY_LARGE_MB( \
"Memory.Experimental." type "2.PartitionAlloc", \
pmd->chrome_dump->partition_alloc_total_kb / 1024); \
UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Experimental." type "2.BlinkGC", \
pmd->chrome_dump->blink_gc_total_kb / 1024); \
UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Experimental." type "2.V8", \
pmd->chrome_dump->v8_total_kb / 1024); \
} while (false)
void EmitRendererMemoryMetrics(const ProcessMemoryDumpPtr& pmd,
ukm::SourceId ukm_source_id,
ukm::UkmRecorder* ukm_recorder) {
ukm::UkmRecorder* ukm_recorder,
int number_of_extensions) {
// UMA
if (number_of_extensions == 0) {
RENDERER_MEMORY_UMA_HISTOGRAMS("Renderer");
} else {
RENDERER_MEMORY_UMA_HISTOGRAMS("Extension");
}
// UKM
ukm::builders::Memory_Experimental builder(ukm_source_id);
builder.SetProcessType(static_cast<int64_t>(
memory_instrumentation::mojom::ProcessType::RENDERER));
UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Experimental.Renderer2.Resident",
pmd->os_dump->resident_set_kb / 1024);
builder.SetResident(pmd->os_dump->resident_set_kb / 1024);
UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Experimental.Renderer2.Malloc",
pmd->chrome_dump->malloc_total_kb / 1024);
builder.SetMalloc(pmd->chrome_dump->malloc_total_kb / 1024);
UMA_HISTOGRAM_MEMORY_LARGE_MB(
"Memory.Experimental.Renderer2.PrivateMemoryFootprint",
pmd->os_dump->private_footprint_kb / 1024);
UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Renderer.PrivateMemoryFootprint",
pmd->os_dump->private_footprint_kb / 1024);
builder.SetPrivateMemoryFootprint(pmd->os_dump->private_footprint_kb / 1024);
UMA_HISTOGRAM_MEMORY_LARGE_MB(
"Memory.Experimental.Renderer2.PartitionAlloc",
pmd->chrome_dump->partition_alloc_total_kb / 1024);
builder.SetPartitionAlloc(pmd->chrome_dump->partition_alloc_total_kb / 1024);
UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Experimental.Renderer2.BlinkGC",
pmd->chrome_dump->blink_gc_total_kb / 1024);
builder.SetBlinkGC(pmd->chrome_dump->blink_gc_total_kb / 1024);
UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Experimental.Renderer2.V8",
pmd->chrome_dump->v8_total_kb / 1024);
builder.SetV8(pmd->chrome_dump->v8_total_kb / 1024);
builder.SetNumberOfExtensions(number_of_extensions);
builder.Record(ukm_recorder);
}
......@@ -183,6 +200,43 @@ ukm::UkmRecorder* ProcessMemoryMetricsEmitter::GetUkmRecorder() {
return ukm::UkmRecorder::Get();
}
int ProcessMemoryMetricsEmitter::GetNumberOfExtensions(base::ProcessId pid) {
int number_of_extensions = 0;
#if BUILDFLAG(ENABLE_EXTENSIONS)
// Retrieve the renderer process host for the given pid.
int rph_id = -1;
auto iter = content::RenderProcessHost::AllHostsIterator();
while (!iter.IsAtEnd()) {
if (base::GetProcId(iter.GetCurrentValue()->GetHandle()) == pid) {
rph_id = iter.GetCurrentValue()->GetID();
break;
}
iter.Advance();
}
if (iter.IsAtEnd())
return 0;
// Count the number of extensions associated with that renderer process host
// in all profiles.
for (Profile* profile :
g_browser_process->profile_manager()->GetLoadedProfiles()) {
extensions::ProcessMap* process_map = extensions::ProcessMap::Get(profile);
extensions::ExtensionRegistry* registry =
extensions::ExtensionRegistry::Get(profile);
std::set<std::string> extension_ids =
process_map->GetExtensionsInProcess(rph_id);
for (const std::string& extension_id : extension_ids) {
// Only count non hosted apps extensions.
const extensions::Extension* extension =
registry->enabled_extensions().GetByID(extension_id);
if (!extension->is_hosted_app())
number_of_extensions++;
}
}
#endif
return number_of_extensions;
}
void ProcessMemoryMetricsEmitter::CollateResults() {
if (memory_dump_in_progress_ || get_process_urls_in_progress_)
return;
......@@ -192,7 +246,6 @@ void ProcessMemoryMetricsEmitter::CollateResults() {
uint32_t private_footprint_total_kb = 0;
for (const ProcessMemoryDumpPtr& pmd : global_dump_->process_dumps) {
private_footprint_total_kb += pmd->os_dump->private_footprint_kb;
switch (pmd->process_type) {
case memory_instrumentation::mojom::ProcessType::BROWSER: {
EmitBrowserMemoryMetrics(pmd, ukm::UkmRecorder::GetNewSourceID(),
......@@ -211,7 +264,9 @@ void ProcessMemoryMetricsEmitter::CollateResults() {
ukm_source_id = process_info->ukm_source_ids[0];
}
}
EmitRendererMemoryMetrics(pmd, ukm_source_id, GetUkmRecorder());
int number_of_extensions = GetNumberOfExtensions(pmd->pid);
EmitRendererMemoryMetrics(pmd, ukm_source_id, GetUkmRecorder(),
number_of_extensions);
break;
}
case memory_instrumentation::mojom::ProcessType::GPU: {
......
......@@ -9,6 +9,7 @@
#include <vector>
#include "base/memory/ref_counted.h"
#include "base/process/process_handle.h"
#include "services/resource_coordinator/public/interfaces/coordination_unit_introspector.mojom.h"
#include "services/resource_coordinator/public/interfaces/memory_instrumentation/memory_instrumentation.mojom.h"
......@@ -55,6 +56,10 @@ class ProcessMemoryMetricsEmitter
// Virtual for testing.
virtual ukm::UkmRecorder* GetUkmRecorder();
// Virtual for testing. Returns the number of extensions in the given process.
// It excludes hosted apps extensions.
virtual int GetNumberOfExtensions(base::ProcessId pid);
private:
friend class base::RefCountedThreadSafe<ProcessMemoryMetricsEmitter>;
......
......@@ -6,6 +6,7 @@
#include "base/containers/flat_map.h"
#include "base/memory/ref_counted.h"
#include "base/process/process_handle.h"
#include "components/ukm/test_ukm_recorder.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -46,6 +47,15 @@ class ProcessMemoryMetricsEmitterFake : public ProcessMemoryMetricsEmitter {
ukm::UkmRecorder* GetUkmRecorder() override { return ukm_recorder_; }
int GetNumberOfExtensions(base::ProcessId pid) override {
switch (pid) {
case 401:
return 1;
default:
return 0;
}
}
private:
~ProcessMemoryMetricsEmitterFake() override {}
......@@ -129,6 +139,7 @@ base::flat_map<const char*, int64_t> GetExpectedRendererMetrics() {
{"PartitionAlloc", 140},
{"BlinkGC", 150},
{"V8", 160},
{"NumberOfExtensions", 0},
},
base::KEEP_FIRST_OF_DUPES);
}
......@@ -301,6 +312,25 @@ INSTANTIATE_TEST_CASE_P(SinglePtype,
ProcessType::RENDERER,
ProcessType::GPU));
TEST_F(ProcessMemoryMetricsEmitterTest, CollectsExtensionProcessUKMs) {
base::flat_map<const char*, int64_t> expected_metrics =
GetExpectedRendererMetrics();
expected_metrics["NumberOfExtensions"] = 1;
uint64_t dump_guid = 333;
GlobalMemoryDumpPtr global_dump(
memory_instrumentation::mojom::GlobalMemoryDump::New());
PopulateRendererMetrics(global_dump, expected_metrics, 401);
scoped_refptr<ProcessMemoryMetricsEmitterFake> emitter(
new ProcessMemoryMetricsEmitterFake(test_ukm_recorder_));
emitter->ReceivedProcessInfos(ProcessInfoVector());
emitter->ReceivedMemoryDump(true, dump_guid, std::move(global_dump));
EXPECT_EQ(2u, test_ukm_recorder_.entries_count());
CheckMemoryUkmEntryMetrics(0, expected_metrics);
}
TEST_F(ProcessMemoryMetricsEmitterTest, CollectsManyProcessUKMsSingleDump) {
std::vector<ProcessType> entries_ptypes = {
ProcessType::BROWSER, ProcessType::RENDERER, ProcessType::GPU,
......
......@@ -33408,6 +33408,16 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries.
</summary>
</histogram>
<histogram base="true" name="Memory.Experimental.Extension2" units="MB">
<!-- Name completed by histogram_suffixes name="RendererMemoryAllocator2" -->
<owner>erikchen@chromium.org</owner>
<summary>
The extension process's memory usage reported by the memory instrumentation
service.
</summary>
</histogram>
<histogram name="Memory.Experimental.Gpu.PhysicalFootprint.MacOS" units="MB">
<owner>erikchen@chromium.org</owner>
<summary>
......@@ -33521,6 +33531,14 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries.
</summary>
</histogram>
<histogram name="Memory.Extension.PrivateMemoryFootprint" units="MB">
<owner>erikchen@chromium.org</owner>
<summary>
A rough estimate of the private memory footprint of the extension process.
Recorded once per UMA ping.
</summary>
</histogram>
<histogram name="Memory.ExtensionProcessCount" units="processes">
<owner>hajimehoshi@chromium.org</owner>
<owner>kenjibaheux@google.com</owner>
......@@ -99401,6 +99419,7 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries.
<suffix name="PartitionAlloc" label="Constrained to partition allocator."/>
<suffix name="BlinkGC" label="Constrained to blink GC allocator."/>
<suffix name="V8" label="Constrained to v8 allocator."/>
<affected-histogram name="Memory.Experimental.Extension2"/>
<affected-histogram name="Memory.Experimental.Renderer2"/>
</histogram_suffixes>
......@@ -595,6 +595,12 @@ be describing additional metrics about the same event.
Measure of memory allocated by malloc.
</summary>
</metric>
<metric name="NumberOfExtensions">
<summary>
The number of extensions that are served from the associated renderer
process.
</summary>
</metric>
<metric name="PartitionAlloc">
<summary>
Measure of memory allocated by PartitionAlloc.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment