Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(650)

Unified Diff: chrome/browser/metrics/metrics_memory_details.cc

Issue 823533004: Move memory histograms generation to MetricsMemoryDetails. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: clang-format Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/metrics/metrics_memory_details.cc
diff --git a/chrome/browser/metrics/metrics_memory_details.cc b/chrome/browser/metrics/metrics_memory_details.cc
new file mode 100644
index 0000000000000000000000000000000000000000..3d1aa61ea9073c0089de3072344de0698d08b767
--- /dev/null
+++ b/chrome/browser/metrics/metrics_memory_details.cc
@@ -0,0 +1,296 @@
+// Copyright 2015 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 "chrome/browser/metrics/metrics_memory_details.h"
+
+#include <vector>
+
+#include "base/message_loop/message_loop.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/strings/utf_string_conversions.h"
+#include "components/nacl/common/nacl_process_type.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/common/content_constants.h"
+#include "content/public/common/process_type.h"
+
+MemoryGrowthTracker::MemoryGrowthTracker() {
+}
+
+MemoryGrowthTracker::~MemoryGrowthTracker() {
+}
+
+bool MemoryGrowthTracker::UpdateSample(base::ProcessId pid,
+ int sample,
+ int* diff) {
+ // |sample| is memory usage in kB.
+ const base::TimeTicks current_time = base::TimeTicks::Now();
+ std::map<base::ProcessId, int>::iterator found_size = memory_sizes_.find(pid);
+ if (found_size != memory_sizes_.end()) {
+ const int last_size = found_size->second;
+ std::map<base::ProcessId, base::TimeTicks>::iterator found_time =
+ times_.find(pid);
+ const base::TimeTicks last_time = found_time->second;
+ if (last_time < (current_time - base::TimeDelta::FromMinutes(30))) {
+ // Note that it is undefined how division of a negative integer gets
+ // rounded. |*diff| may have a difference of 1 from the correct number
+ // if |sample| < |last_size|. We ignore it as 1 is small enough.
+ *diff =
+ ((sample - last_size) * 30 / (current_time - last_time).InMinutes());
+ found_size->second = sample;
+ found_time->second = current_time;
+ return true;
+ }
+ // Skip if a last record is found less than 30 minutes ago.
+ } else {
+ // Not reporting if it's the first record for |pid|.
+ times_[pid] = current_time;
+ memory_sizes_[pid] = sample;
+ }
+ return false;
+}
+
+MetricsMemoryDetails::MetricsMemoryDetails(
+ const base::Closure& callback,
+ MemoryGrowthTracker* memory_growth_tracker)
+ : callback_(callback), memory_growth_tracker_(memory_growth_tracker) {
+ memory_growth_tracker_ = memory_growth_tracker;
+}
+
+MetricsMemoryDetails::~MetricsMemoryDetails() {
+}
+
+void MetricsMemoryDetails::OnDetailsAvailable() {
+ UpdateHistograms();
+ base::MessageLoop::current()->PostTask(FROM_HERE, callback_);
+}
+
+void MetricsMemoryDetails::UpdateHistograms() {
+ // Reports a set of memory metrics to UMA.
+ // Memory is measured in KB.
+
+ const ProcessData& browser = *ChromeBrowser();
+ size_t aggregate_memory = 0;
+ int chrome_count = 0;
+ int extension_count = 0;
+ int plugin_count = 0;
+ int pepper_plugin_count = 0;
+ int pepper_plugin_broker_count = 0;
+ int renderer_count = 0;
+ int other_count = 0;
+ int worker_count = 0;
+ int process_limit = content::RenderProcessHost::GetMaxRendererProcessCount();
+ for (size_t index = 0; index < browser.processes.size(); index++) {
+ int sample = static_cast<int>(browser.processes[index].working_set.priv);
+ aggregate_memory += sample;
+ switch (browser.processes[index].process_type) {
+ case content::PROCESS_TYPE_BROWSER:
+ UMA_HISTOGRAM_MEMORY_KB("Memory.Browser", sample);
+ continue;
+ case content::PROCESS_TYPE_RENDERER: {
+ ProcessMemoryInformation::RendererProcessType renderer_type =
+ browser.processes[index].renderer_type;
+ switch (renderer_type) {
+ case ProcessMemoryInformation::RENDERER_EXTENSION:
+ UMA_HISTOGRAM_MEMORY_KB("Memory.Extension", sample);
+ extension_count++;
+ continue;
+ case ProcessMemoryInformation::RENDERER_CHROME:
+ UMA_HISTOGRAM_MEMORY_KB("Memory.Chrome", sample);
+ chrome_count++;
+ continue;
+ case ProcessMemoryInformation::RENDERER_UNKNOWN:
+ NOTREACHED() << "Unknown renderer process type.";
+ continue;
+ case ProcessMemoryInformation::RENDERER_NORMAL:
+ default:
+ // TODO(erikkay): Should we bother splitting out the other subtypes?
+ UMA_HISTOGRAM_MEMORY_KB("Memory.Renderer", sample);
+ int diff;
+ if (memory_growth_tracker_ &&
+ memory_growth_tracker_->UpdateSample(
+ browser.processes[index].pid, sample, &diff)) {
+ if (diff < 0)
+ UMA_HISTOGRAM_MEMORY_KB("Memory.RendererShrinkIn30Min", -diff);
+ else
+ UMA_HISTOGRAM_MEMORY_KB("Memory.RendererGrowthIn30Min", diff);
+ }
+ renderer_count++;
+ continue;
+ }
+ }
+ case content::PROCESS_TYPE_PLUGIN:
+ UMA_HISTOGRAM_MEMORY_KB("Memory.Plugin", sample);
+ plugin_count++;
+ continue;
+ case content::PROCESS_TYPE_UTILITY:
+ UMA_HISTOGRAM_MEMORY_KB("Memory.Utility", sample);
+ other_count++;
+ continue;
+ case content::PROCESS_TYPE_ZYGOTE:
+ UMA_HISTOGRAM_MEMORY_KB("Memory.Zygote", sample);
+ other_count++;
+ continue;
+ case content::PROCESS_TYPE_SANDBOX_HELPER:
+ UMA_HISTOGRAM_MEMORY_KB("Memory.SandboxHelper", sample);
+ other_count++;
+ continue;
+ case content::PROCESS_TYPE_GPU:
+ UMA_HISTOGRAM_MEMORY_KB("Memory.Gpu", sample);
+ other_count++;
+ continue;
+#if defined(ENABLE_PLUGINS)
+ case content::PROCESS_TYPE_PPAPI_PLUGIN: {
+ const std::vector<base::string16>& titles =
+ browser.processes[index].titles;
+ if (titles.size() == 1 &&
+ titles[0] == base::ASCIIToUTF16(content::kFlashPluginName)) {
+ UMA_HISTOGRAM_MEMORY_KB("Memory.PepperFlashPlugin", sample);
+ }
+ }
Ilya Sherman 2015/01/16 04:57:36 nit: The placement of this curly brace looks reall
Alexei Svitkine (slow) 2015/01/16 16:07:49 Indeed - I guess clang format got confused here. F
+ UMA_HISTOGRAM_MEMORY_KB("Memory.PepperPlugin", sample);
+ pepper_plugin_count++;
+ continue;
+ case content::PROCESS_TYPE_PPAPI_BROKER:
+ UMA_HISTOGRAM_MEMORY_KB("Memory.PepperPluginBroker", sample);
+ pepper_plugin_broker_count++;
+ continue;
+#endif
+ case PROCESS_TYPE_NACL_LOADER:
+ UMA_HISTOGRAM_MEMORY_KB("Memory.NativeClient", sample);
+ other_count++;
+ continue;
+ case PROCESS_TYPE_NACL_BROKER:
+ UMA_HISTOGRAM_MEMORY_KB("Memory.NativeClientBroker", sample);
+ other_count++;
+ continue;
+ default:
+ NOTREACHED();
+ continue;
+ }
+ }
+#if defined(OS_CHROMEOS)
+ // Chrome OS exposes system-wide graphics driver memory which has historically
+ // been a source of leak/bloat.
+ base::SystemMemoryInfoKB meminfo;
+ if (base::GetSystemMemoryInfo(&meminfo) && meminfo.gem_size != -1)
+ UMA_HISTOGRAM_MEMORY_MB("Memory.Graphics", meminfo.gem_size / 1024 / 1024);
+#endif
+
+ UMA_HISTOGRAM_COUNTS_100("Memory.ProcessLimit", process_limit);
+ UMA_HISTOGRAM_COUNTS_100("Memory.ProcessCount",
+ static_cast<int>(browser.processes.size()));
+ UMA_HISTOGRAM_COUNTS_100("Memory.ChromeProcessCount", chrome_count);
+ UMA_HISTOGRAM_COUNTS_100("Memory.ExtensionProcessCount", extension_count);
+ UMA_HISTOGRAM_COUNTS_100("Memory.OtherProcessCount", other_count);
+ UMA_HISTOGRAM_COUNTS_100("Memory.PluginProcessCount", plugin_count);
+ UMA_HISTOGRAM_COUNTS_100("Memory.PepperPluginProcessCount",
+ pepper_plugin_count);
+ UMA_HISTOGRAM_COUNTS_100("Memory.PepperPluginBrokerProcessCount",
+ pepper_plugin_broker_count);
+ UMA_HISTOGRAM_COUNTS_100("Memory.RendererProcessCount", renderer_count);
+ UMA_HISTOGRAM_COUNTS_100("Memory.WorkerProcessCount", worker_count);
+ // TODO(viettrungluu): Do we want separate counts for the other
+ // (platform-specific) process types?
+
+ int total_sample = static_cast<int>(aggregate_memory / 1000);
+ UMA_HISTOGRAM_MEMORY_MB("Memory.Total", total_sample);
+
+#if defined(OS_CHROMEOS)
+ UpdateSwapHistograms();
+#endif
+}
+
+#if defined(OS_CHROMEOS)
+void MetricsMemoryDetails::UpdateSwapHistograms() {
+ UMA_HISTOGRAM_BOOLEAN("Memory.Swap.HaveSwapped", swap_info().num_writes > 0);
+ if (swap_info().num_writes == 0)
+ return;
+
+ // Only record swap info when any swaps have happened, to give us more
+ // detail in the histograms.
+ const ProcessData& browser = *ChromeBrowser();
+ size_t aggregate_memory = 0;
+ for (size_t index = 0; index < browser.processes.size(); index++) {
+ int sample = static_cast<int>(browser.processes[index].working_set.swapped);
+ aggregate_memory += sample;
+ switch (browser.processes[index].process_type) {
+ case content::PROCESS_TYPE_BROWSER:
+ UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Browser", sample);
+ continue;
+ case content::PROCESS_TYPE_RENDERER: {
+ ProcessMemoryInformation::RendererProcessType renderer_type =
+ browser.processes[index].renderer_type;
+ switch (renderer_type) {
+ case ProcessMemoryInformation::RENDERER_EXTENSION:
+ UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Extension", sample);
+ continue;
+ case ProcessMemoryInformation::RENDERER_CHROME:
+ UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Chrome", sample);
+ continue;
+ case ProcessMemoryInformation::RENDERER_UNKNOWN:
+ NOTREACHED() << "Unknown renderer process type.";
+ continue;
+ case ProcessMemoryInformation::RENDERER_NORMAL:
+ default:
+ UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Renderer", sample);
+ continue;
+ }
+ }
+ case content::PROCESS_TYPE_PLUGIN:
+ UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Plugin", sample);
+ continue;
+ case content::PROCESS_TYPE_UTILITY:
+ UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Utility", sample);
+ continue;
+ case content::PROCESS_TYPE_ZYGOTE:
+ UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Zygote", sample);
+ continue;
+ case content::PROCESS_TYPE_SANDBOX_HELPER:
+ UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.SandboxHelper", sample);
+ continue;
+ case content::PROCESS_TYPE_GPU:
+ UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Gpu", sample);
+ continue;
+ case content::PROCESS_TYPE_PPAPI_PLUGIN:
+ UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.PepperPlugin", sample);
+ continue;
+ case content::PROCESS_TYPE_PPAPI_BROKER:
+ UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.PepperPluginBroker", sample);
+ continue;
+ case PROCESS_TYPE_NACL_LOADER:
+ UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.NativeClient", sample);
+ continue;
+ case PROCESS_TYPE_NACL_BROKER:
+ UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.NativeClientBroker", sample);
+ continue;
+ default:
+ NOTREACHED();
+ continue;
+ }
+ }
+
+ int total_sample = static_cast<int>(aggregate_memory / 1000);
+ UMA_HISTOGRAM_MEMORY_MB("Memory.Swap.Total", total_sample);
+
+ UMA_HISTOGRAM_CUSTOM_COUNTS("Memory.Swap.CompressedDataSize",
+ swap_info().compr_data_size / (1024 * 1024), 1,
+ 4096, 50);
+ UMA_HISTOGRAM_CUSTOM_COUNTS("Memory.Swap.OriginalDataSize",
+ swap_info().orig_data_size / (1024 * 1024), 1,
+ 4096, 50);
+ UMA_HISTOGRAM_CUSTOM_COUNTS("Memory.Swap.MemUsedTotal",
+ swap_info().mem_used_total / (1024 * 1024), 1,
+ 4096, 50);
+ UMA_HISTOGRAM_CUSTOM_COUNTS("Memory.Swap.NumReads", swap_info().num_reads, 1,
+ 100000000, 100);
+ UMA_HISTOGRAM_CUSTOM_COUNTS("Memory.Swap.NumWrites", swap_info().num_writes,
+ 1, 100000000, 100);
+
+ if (swap_info().orig_data_size > 0 && swap_info().compr_data_size > 0) {
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "Memory.Swap.CompressionRatio",
+ swap_info().orig_data_size / swap_info().compr_data_size, 1, 20, 20);
+ }
+}
+#endif // defined(OS_CHROMEOS)

Powered by Google App Engine
This is Rietveld 408576698