Commit b67d830f authored by Francois Doray's avatar Francois Doray Committed by Commit Bot

Add Memory.*.ResidentSet histograms.

These histograms record the size of the resident memory per process type and in
total. Resident memory is influenced by factors we control (e.g. memory that is
not accessed can be swapped) and factors we don't control (e.g. an unrelated
process using a lot of memory can force memory in our process to be swapped).
Histograms are recorded once per UMA ping.

These histograms are added to answer the following question:
- Do the efforts we make to reduce the amount of memory accessed by frozen
  renderers has an impact on the size of their working set?

Bug: 885293
Change-Id: I7cb3b1b5bd4d927277f5f4c9e96455dc0ff2ef94
Reviewed-on: https://chromium-review.googlesource.com/c/1301847
Commit-Queue: François Doray <fdoray@chromium.org>
Reviewed-by: default avatarBrian White <bcwhite@chromium.org>
Cr-Commit-Position: refs/heads/master@{#604654}
parent 9e7f34f7
...@@ -305,7 +305,12 @@ void EmitProcessUkm(const GlobalMemoryDump::ProcessDump& pmd, ...@@ -305,7 +305,12 @@ void EmitProcessUkm(const GlobalMemoryDump::ProcessDump& pmd,
} }
} }
} }
#if !defined(OS_MACOSX)
// Resident set is not populated on Mac.
builder->SetResident(pmd.os_dump().resident_set_kb / 1024); builder->SetResident(pmd.os_dump().resident_set_kb / 1024);
#endif
builder->SetPrivateMemoryFootprint(pmd.os_dump().private_footprint_kb / 1024); builder->SetPrivateMemoryFootprint(pmd.os_dump().private_footprint_kb / 1024);
builder->SetSharedMemoryFootprint(pmd.os_dump().shared_footprint_kb / 1024); builder->SetSharedMemoryFootprint(pmd.os_dump().shared_footprint_kb / 1024);
#if defined(OS_LINUX) || defined(OS_ANDROID) #if defined(OS_LINUX) || defined(OS_ANDROID)
...@@ -317,6 +322,14 @@ void EmitProcessUkm(const GlobalMemoryDump::ProcessDump& pmd, ...@@ -317,6 +322,14 @@ void EmitProcessUkm(const GlobalMemoryDump::ProcessDump& pmd,
if (!record_uma) if (!record_uma)
return; return;
#if defined(OS_MACOSX)
// Resident set is not populated on Mac.
DCHECK_EQ(pmd.os_dump().resident_set_kb, 0U);
#else
MEMORY_METRICS_HISTOGRAM_MB(
std::string(UMA_PREFIX) + process_name + ".ResidentSet",
pmd.os_dump().resident_set_kb / 1024);
#endif
MEMORY_METRICS_HISTOGRAM_MB( MEMORY_METRICS_HISTOGRAM_MB(
std::string(UMA_PREFIX) + process_name + ".PrivateMemoryFootprint", std::string(UMA_PREFIX) + process_name + ".PrivateMemoryFootprint",
pmd.os_dump().private_footprint_kb / 1024); pmd.os_dump().private_footprint_kb / 1024);
...@@ -545,6 +558,7 @@ void ProcessMemoryMetricsEmitter::CollateResults() { ...@@ -545,6 +558,7 @@ void ProcessMemoryMetricsEmitter::CollateResults() {
uint32_t private_footprint_total_kb = 0; uint32_t private_footprint_total_kb = 0;
uint32_t renderer_private_footprint_total_kb = 0; uint32_t renderer_private_footprint_total_kb = 0;
uint32_t shared_footprint_total_kb = 0; uint32_t shared_footprint_total_kb = 0;
uint32_t resident_set_total_kb = 0;
bool emit_metrics_for_all_processes = pid_scope_ == base::kNullProcessId; bool emit_metrics_for_all_processes = pid_scope_ == base::kNullProcessId;
TabFootprintAggregator per_tab_metrics; TabFootprintAggregator per_tab_metrics;
...@@ -554,6 +568,7 @@ void ProcessMemoryMetricsEmitter::CollateResults() { ...@@ -554,6 +568,7 @@ void ProcessMemoryMetricsEmitter::CollateResults() {
uint32_t process_pmf_kb = pmd.os_dump().private_footprint_kb; uint32_t process_pmf_kb = pmd.os_dump().private_footprint_kb;
private_footprint_total_kb += process_pmf_kb; private_footprint_total_kb += process_pmf_kb;
shared_footprint_total_kb += pmd.os_dump().shared_footprint_kb; shared_footprint_total_kb += pmd.os_dump().shared_footprint_kb;
resident_set_total_kb += pmd.os_dump().resident_set_kb;
if (!emit_metrics_for_all_processes && pid_scope_ != pmd.pid()) if (!emit_metrics_for_all_processes && pid_scope_ != pmd.pid())
continue; continue;
...@@ -636,6 +651,14 @@ void ProcessMemoryMetricsEmitter::CollateResults() { ...@@ -636,6 +651,14 @@ void ProcessMemoryMetricsEmitter::CollateResults() {
UMA_HISTOGRAM_MEMORY_LARGE_MB( UMA_HISTOGRAM_MEMORY_LARGE_MB(
"Memory.Experimental.Total2.PrivateMemoryFootprint", "Memory.Experimental.Total2.PrivateMemoryFootprint",
private_footprint_total_kb / 1024); private_footprint_total_kb / 1024);
#if defined(OS_MACOSX)
// Resident set is not populated on Mac.
DCHECK_EQ(resident_set_total_kb, 0U);
#else
UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Total.ResidentSet",
resident_set_total_kb / 1024);
#endif
UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Total.PrivateMemoryFootprint", UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Total.PrivateMemoryFootprint",
private_footprint_total_kb / 1024); private_footprint_total_kb / 1024);
UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Total.RendererPrivateMemoryFootprint", UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Total.RendererPrivateMemoryFootprint",
......
...@@ -145,7 +145,7 @@ void CheckMemoryMetric(const std::string& name, ...@@ -145,7 +145,7 @@ void CheckMemoryMetric(const std::string& name,
EXPECT_EQ(samples->TotalCount(), count * number_of_processes) << name; EXPECT_EQ(samples->TotalCount(), count * number_of_processes) << name;
} }
if (value_restriction == ValueRestriction::ABOVE_ZERO) if (count != 0 && value_restriction == ValueRestriction::ABOVE_ZERO)
EXPECT_GT(samples->sum(), 0u) << name; EXPECT_GT(samples->sum(), 0u) << name;
// As a sanity check, no memory stat should exceed 4 GB. // As a sanity check, no memory stat should exceed 4 GB.
...@@ -153,10 +153,11 @@ void CheckMemoryMetric(const std::string& name, ...@@ -153,10 +153,11 @@ void CheckMemoryMetric(const std::string& name,
EXPECT_LT(samples->sum(), maximum_expected_size) << name; EXPECT_LT(samples->sum(), maximum_expected_size) << name;
} }
void CheckAllMemoryMetrics(const base::HistogramTester& histogram_tester, void CheckExperimentalMemoryMetrics(
int count, const base::HistogramTester& histogram_tester,
int number_of_renderer_processes = 1u, int count,
int number_of_extenstion_processes = 0u) { int number_of_renderer_processes,
int number_of_extension_processes) {
#if !defined(OS_WIN) #if !defined(OS_WIN)
CheckMemoryMetric("Memory.Experimental.Browser2.Malloc", histogram_tester, CheckMemoryMetric("Memory.Experimental.Browser2.Malloc", histogram_tester,
count, ValueRestriction::ABOVE_ZERO); count, ValueRestriction::ABOVE_ZERO);
...@@ -177,26 +178,98 @@ void CheckAllMemoryMetrics(const base::HistogramTester& histogram_tester, ...@@ -177,26 +178,98 @@ void CheckAllMemoryMetrics(const base::HistogramTester& histogram_tester,
count, ValueRestriction::ABOVE_ZERO, count, ValueRestriction::ABOVE_ZERO,
number_of_renderer_processes); number_of_renderer_processes);
} }
if (number_of_extenstion_processes) { if (number_of_extension_processes) {
#if !defined(OS_WIN) #if !defined(OS_WIN)
CheckMemoryMetric("Memory.Experimental.Extension2.Malloc", histogram_tester, CheckMemoryMetric("Memory.Experimental.Extension2.Malloc", histogram_tester,
count, ValueRestriction::ABOVE_ZERO, count, ValueRestriction::ABOVE_ZERO,
number_of_extenstion_processes); number_of_extension_processes);
#endif #endif
CheckMemoryMetric("Memory.Experimental.Extension2.BlinkGC", CheckMemoryMetric("Memory.Experimental.Extension2.BlinkGC",
histogram_tester, count, ValueRestriction::NONE, histogram_tester, count, ValueRestriction::NONE,
number_of_extenstion_processes); number_of_extension_processes);
CheckMemoryMetric("Memory.Experimental.Extension2.PartitionAlloc", CheckMemoryMetric("Memory.Experimental.Extension2.PartitionAlloc",
histogram_tester, count, ValueRestriction::NONE, histogram_tester, count, ValueRestriction::NONE,
number_of_extenstion_processes); number_of_extension_processes);
CheckMemoryMetric("Memory.Experimental.Extension2.V8", histogram_tester, CheckMemoryMetric("Memory.Experimental.Extension2.V8", histogram_tester,
count, ValueRestriction::ABOVE_ZERO, count, ValueRestriction::ABOVE_ZERO,
number_of_extenstion_processes); number_of_extension_processes);
} }
CheckMemoryMetric("Memory.Experimental.Total2.PrivateMemoryFootprint", CheckMemoryMetric("Memory.Experimental.Total2.PrivateMemoryFootprint",
histogram_tester, count, ValueRestriction::ABOVE_ZERO); histogram_tester, count, ValueRestriction::ABOVE_ZERO);
} }
void CheckStableMemoryMetrics(const base::HistogramTester& histogram_tester,
int count,
int number_of_renderer_processes,
int number_of_extension_processes) {
const int count_for_resident_set =
#if defined(OS_MACOSX)
0;
#else
count;
#endif
const int count_for_private_swap_footprint =
#if defined(OS_LINUX) || defined(OS_ANDROID)
count;
#else
0;
#endif
if (number_of_renderer_processes) {
CheckMemoryMetric("Memory.Renderer.ResidentSet", histogram_tester,
count_for_resident_set, ValueRestriction::ABOVE_ZERO,
number_of_renderer_processes);
CheckMemoryMetric("Memory.Renderer.PrivateMemoryFootprint",
histogram_tester, count, ValueRestriction::ABOVE_ZERO,
number_of_renderer_processes);
// Shared memory footprint can be below 1 MB, which is reported as zero.
CheckMemoryMetric("Memory.Renderer.SharedMemoryFootprint", histogram_tester,
count, ValueRestriction::NONE,
number_of_renderer_processes);
CheckMemoryMetric("Memory.Renderer.PrivateSwapFootprint", histogram_tester,
count_for_private_swap_footprint, ValueRestriction::NONE,
number_of_renderer_processes);
}
if (number_of_extension_processes) {
CheckMemoryMetric("Memory.Extension.ResidentSet", histogram_tester,
count_for_resident_set, ValueRestriction::ABOVE_ZERO,
number_of_extension_processes);
CheckMemoryMetric("Memory.Extension.PrivateMemoryFootprint",
histogram_tester, count, ValueRestriction::ABOVE_ZERO,
number_of_extension_processes);
// Shared memory footprint can be below 1 MB, which is reported as zero.
CheckMemoryMetric("Memory.Extension.SharedMemoryFootprint",
histogram_tester, count, ValueRestriction::NONE,
number_of_extension_processes);
CheckMemoryMetric("Memory.Extension.PrivateSwapFootprint", histogram_tester,
count_for_private_swap_footprint, ValueRestriction::NONE,
number_of_extension_processes);
}
CheckMemoryMetric("Memory.Total.ResidentSet", histogram_tester,
count_for_resident_set, ValueRestriction::ABOVE_ZERO);
CheckMemoryMetric("Memory.Total.PrivateMemoryFootprint", histogram_tester,
count, ValueRestriction::ABOVE_ZERO);
CheckMemoryMetric("Memory.Total.RendererPrivateMemoryFootprint",
histogram_tester, count, ValueRestriction::ABOVE_ZERO);
// Shared memory footprint can be below 1 MB, which is reported as zero.
CheckMemoryMetric("Memory.Total.SharedMemoryFootprint", histogram_tester,
count, ValueRestriction::NONE);
}
void CheckAllMemoryMetrics(const base::HistogramTester& histogram_tester,
int count,
int number_of_renderer_processes = 1u,
int number_of_extension_processes = 0u) {
CheckExperimentalMemoryMetrics(histogram_tester, count,
number_of_renderer_processes,
number_of_extension_processes);
CheckStableMemoryMetrics(histogram_tester, count,
number_of_renderer_processes,
number_of_extension_processes);
}
} // namespace } // namespace
class ProcessMemoryMetricsEmitterTest class ProcessMemoryMetricsEmitterTest
......
...@@ -47549,6 +47549,18 @@ uploading your change for review. ...@@ -47549,6 +47549,18 @@ uploading your change for review.
</summary> </summary>
</histogram> </histogram>
<histogram name="Memory.AudioService.ResidentSet" units="MiB"
expires_after="2019-01-31">
<owner>fdoray@chromium.org</owner>
<summary>
The size of the resident memory in a audio service process. This is
influenced by factors we control (e.g. memory that is not accessed can be
swapped) and factors we don't control (e.g. an unrelated process using a lot
of memory can force memory in our process to be swapped). Recorded once per
UMA ping on Windows/Linux/ChromeOS/Android.
</summary>
</histogram>
<histogram name="Memory.AudioService.SharedMemoryFootprint" units="MB"> <histogram name="Memory.AudioService.SharedMemoryFootprint" units="MB">
<owner>marinaciocea@chromium.org</owner> <owner>marinaciocea@chromium.org</owner>
<owner>maxmorin@chromium.org</owner> <owner>maxmorin@chromium.org</owner>
...@@ -47634,6 +47646,18 @@ uploading your change for review. ...@@ -47634,6 +47646,18 @@ uploading your change for review.
</summary> </summary>
</histogram> </histogram>
<histogram name="Memory.Browser.ResidentSet" units="MiB"
expires_after="2019-01-31">
<owner>fdoray@chromium.org</owner>
<summary>
The size of the resident memory in the browser process. This is influenced
by factors we control (e.g. memory that is not accessed can be swapped) and
factors we don't control (e.g. an unrelated process using a lot of memory
can force memory in our process to be swapped). Recorded once per UMA ping
on Windows/Linux/ChromeOS/Android.
</summary>
</histogram>
<histogram name="Memory.Browser.SharedMemoryFootprint" units="MB"> <histogram name="Memory.Browser.SharedMemoryFootprint" units="MB">
<owner>erikchen@chromium.org</owner> <owner>erikchen@chromium.org</owner>
<summary> <summary>
...@@ -48306,6 +48330,18 @@ uploading your change for review. ...@@ -48306,6 +48330,18 @@ uploading your change for review.
</summary> </summary>
</histogram> </histogram>
<histogram name="Memory.Extension.ResidentSet" units="MiB"
expires_after="2019-01-31">
<owner>fdoray@chromium.org</owner>
<summary>
The size of the resident memory in an extension process. This is influenced
by factors we control (e.g. memory that is not accessed can be swapped) and
factors we don't control (e.g. an unrelated process using a lot of memory
can force memory in our process to be swapped). Recorded once per UMA ping
on Windows/Linux/ChromeOS/Android.
</summary>
</histogram>
<histogram name="Memory.Extension.SharedMemoryFootprint" units="MB"> <histogram name="Memory.Extension.SharedMemoryFootprint" units="MB">
<owner>erikchen@chromium.org</owner> <owner>erikchen@chromium.org</owner>
<owner>ssid@chromium.org</owner> <owner>ssid@chromium.org</owner>
...@@ -48374,6 +48410,17 @@ uploading your change for review. ...@@ -48374,6 +48410,17 @@ uploading your change for review.
</summary> </summary>
</histogram> </histogram>
<histogram name="Memory.Gpu.ResidentSet" units="MiB" expires_after="2019-01-31">
<owner>fdoray@chromium.org</owner>
<summary>
The size of the resident memory in the GPU process. This is influenced by
factors we control (e.g. memory that is not accessed can be swapped) and
factors we don't control (e.g. an unrelated process using a lot of memory
can force memory in our process to be swapped). Recorded once per UMA ping
on Windows/Linux/ChromeOS/Android.
</summary>
</histogram>
<histogram name="Memory.Gpu.SharedMemoryFootprint" units="MB"> <histogram name="Memory.Gpu.SharedMemoryFootprint" units="MB">
<owner>erikchen@chromium.org</owner> <owner>erikchen@chromium.org</owner>
<owner>ssid@chromium.org</owner> <owner>ssid@chromium.org</owner>
...@@ -48743,6 +48790,18 @@ uploading your change for review. ...@@ -48743,6 +48790,18 @@ uploading your change for review.
</summary> </summary>
</histogram> </histogram>
<histogram name="Memory.Renderer.ResidentSet" units="MiB"
expires_after="2019-01-31">
<owner>fdoray@chromium.org</owner>
<summary>
The size of the resident memory in a renderer process. This is influenced by
factors we control (e.g. memory that is not accessed can be swapped) and
factors we don't control (e.g. an unrelated process using a lot of memory
can force memory in our process to be swapped). Recorded once per UMA ping
on Windows/Linux/ChromeOS/Android.
</summary>
</histogram>
<histogram name="Memory.Renderer.SharedMemoryFootprint" units="MB"> <histogram name="Memory.Renderer.SharedMemoryFootprint" units="MB">
<owner>erikchen@chromium.org</owner> <owner>erikchen@chromium.org</owner>
<owner>ssid@chromium.org</owner> <owner>ssid@chromium.org</owner>
...@@ -49366,6 +49425,18 @@ uploading your change for review. ...@@ -49366,6 +49425,18 @@ uploading your change for review.
</summary> </summary>
</histogram> </histogram>
<histogram name="Memory.Total.ResidentSet" units="MiB"
expires_after="2019-01-31">
<owner>fdoray@chromium.org</owner>
<summary>
The size of the resident memory in all processes. This is influenced by
factors we control (e.g. memory that is not accessed can be swapped) and
factors we don't control (e.g. an unrelated process using a lot of memory
can force memory in our process to be swapped). Recorded once per UMA ping
on Windows/Linux/ChromeOS/Android.
</summary>
</histogram>
<histogram name="Memory.Total.SharedMemoryFootprint" units="MB"> <histogram name="Memory.Total.SharedMemoryFootprint" units="MB">
<owner>erikchen@chromium.org</owner> <owner>erikchen@chromium.org</owner>
<owner>ssid@chromium.org</owner> <owner>ssid@chromium.org</owner>
...@@ -49418,6 +49489,18 @@ uploading your change for review. ...@@ -49418,6 +49489,18 @@ uploading your change for review.
</summary> </summary>
</histogram> </histogram>
<histogram name="Memory.Utility.ResidentSet" units="MiB"
expires_after="2019-01-31">
<owner>fdoray@chromium.org</owner>
<summary>
The size of the resident memory in a utility process. This is influenced by
factors we control (e.g. memory that is not accessed can be swapped) and
factors we don't control (e.g. an unrelated process using a lot of memory
can force memory in our process to be swapped). Recorded once per UMA ping
on Windows/Linux/ChromeOS/Android.
</summary>
</histogram>
<histogram name="Memory.Utility.SharedMemoryFootprint" units="MB"> <histogram name="Memory.Utility.SharedMemoryFootprint" units="MB">
<owner>jam@chromium.org</owner> <owner>jam@chromium.org</owner>
<summary> <summary>
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