blob: 138a51daaf5d18ce1918d4009fb2d0616682d90a [file] [log] [blame]
[email protected]c5dbef02011-05-13 05:06:091// Copyright (c) 2011 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
5#include "chrome/browser/memory_details.h"
initial.commit09911bf2008-07-26 23:55:296
[email protected]24d69692011-10-21 18:26:517#include "base/bind.h"
initial.commit09911bf2008-07-26 23:55:298#include "base/file_version_info.h"
[email protected]835d7c82010-10-14 04:38:389#include "base/metrics/histogram.h"
[email protected]76543b92009-08-31 17:27:4510#include "base/process_util.h"
[email protected]33b9df42010-07-29 06:46:3911#include "base/string_util.h"
[email protected]64048bd2010-03-08 23:28:5812#include "base/utf_string_conversions.h"
[email protected]8add5412011-10-01 21:02:1413#include "chrome/browser/extensions/extension_process_manager.h"
[email protected]79dc42cd2011-01-08 21:43:3514#include "chrome/browser/extensions/extension_service.h"
15#include "chrome/browser/profiles/profile.h"
[email protected]c38831a12011-10-28 12:44:4916#include "chrome/common/chrome_view_types.h"
[email protected]fcf79352010-12-28 20:13:2017#include "chrome/common/extensions/extension.h"
[email protected]cd3d7892009-03-04 23:55:0618#include "chrome/common/url_constants.h"
[email protected]a01efd22011-03-01 00:38:3219#include "content/browser/browser_child_process_host.h"
[email protected]a01efd22011-03-01 00:38:3220#include "content/browser/renderer_host/backing_store_manager.h"
21#include "content/browser/renderer_host/render_process_host.h"
22#include "content/browser/renderer_host/render_view_host.h"
23#include "content/browser/tab_contents/navigation_entry.h"
24#include "content/browser/tab_contents/tab_contents.h"
[email protected]c38831a12011-10-28 12:44:4925#include "content/public/browser/browser_thread.h"
[email protected]e091df82011-10-11 18:13:2126#include "content/public/common/bindings_policy.h"
[email protected]ae5ca892009-07-30 18:00:4727#include "grit/chromium_strings.h"
[email protected]4f260d02010-12-23 18:35:4228#include "grit/generated_resources.h"
[email protected]c051a1b2011-01-21 23:30:1729#include "ui/base/l10n/l10n_util.h"
initial.commit09911bf2008-07-26 23:55:2930
[email protected]1fd5302c2011-05-28 04:06:4331#if defined(OS_POSIX) && !defined(OS_MACOSX)
[email protected]a01efd22011-03-01 00:38:3232#include "content/browser/renderer_host/render_sandbox_host_linux.h"
[email protected]c38831a12011-10-28 12:44:4933#include "content/browser/zygote_host_linux.h"
[email protected]54fd1d32009-09-01 00:12:5834#endif
initial.commit09911bf2008-07-26 23:55:2935
[email protected]631bb742011-11-02 11:29:3936using content::BrowserThread;
37
[email protected]8e383412010-10-19 16:57:0338ProcessMemoryInformation::ProcessMemoryInformation()
39 : pid(0),
40 num_processes(0),
41 is_diagnostics(false),
[email protected]fcf79352010-12-28 20:13:2042 type(ChildProcessInfo::UNKNOWN_PROCESS),
43 renderer_type(ChildProcessInfo::RENDERER_UNKNOWN) {
[email protected]8e383412010-10-19 16:57:0344}
45
46ProcessMemoryInformation::~ProcessMemoryInformation() {}
47
[email protected]93aa89c72010-10-20 21:32:0448ProcessData::ProcessData() {}
49
50ProcessData::ProcessData(const ProcessData& rhs)
51 : name(rhs.name),
52 process_name(rhs.process_name),
53 processes(rhs.processes) {
54}
55
56ProcessData::~ProcessData() {}
57
58ProcessData& ProcessData::operator=(const ProcessData& rhs) {
59 name = rhs.name;
60 process_name = rhs.process_name;
61 processes = rhs.processes;
62 return *this;
63}
64
initial.commit09911bf2008-07-26 23:55:2965// About threading:
66//
67// This operation will hit no fewer than 3 threads.
68//
[email protected]a436d922009-02-13 23:16:4269// The ChildProcessInfo::Iterator can only be accessed from the IO thread.
initial.commit09911bf2008-07-26 23:55:2970//
71// The RenderProcessHostIterator can only be accessed from the UI thread.
72//
73// This operation can take 30-100ms to complete. We never want to have
74// one task run for that long on the UI or IO threads. So, we run the
75// expensive parts of this operation over on the file thread.
76//
initial.commit09911bf2008-07-26 23:55:2977void MemoryDetails::StartFetch() {
[email protected]9bb480ee2011-08-03 21:41:1678 // This might get called from the UI or FILE threads, but should not be
79 // getting called from the IO thread.
[email protected]f8b3ef82010-10-11 02:45:5280 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO));
initial.commit09911bf2008-07-26 23:55:2981
82 // In order to process this request, we need to use the plugin information.
83 // However, plugin process information is only available from the IO thread.
[email protected]f8b3ef82010-10-11 02:45:5284 BrowserThread::PostTask(
85 BrowserThread::IO, FROM_HERE,
[email protected]24d69692011-10-21 18:26:5186 base::Bind(&MemoryDetails::CollectChildInfoOnIOThread, this));
initial.commit09911bf2008-07-26 23:55:2987}
88
[email protected]8e383412010-10-19 16:57:0389MemoryDetails::~MemoryDetails() {}
90
[email protected]a27a9382009-02-11 23:55:1091void MemoryDetails::CollectChildInfoOnIOThread() {
[email protected]f8b3ef82010-10-11 02:45:5292 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
initial.commit09911bf2008-07-26 23:55:2993
[email protected]a27a9382009-02-11 23:55:1094 std::vector<ProcessMemoryInformation> child_info;
95
[email protected]a436d922009-02-13 23:16:4296 // Collect the list of child processes.
[email protected]d27893f62010-07-03 05:47:4297 for (BrowserChildProcessHost::Iterator iter; !iter.Done(); ++iter) {
[email protected]a27a9382009-02-11 23:55:1098 ProcessMemoryInformation info;
[email protected]76543b92009-08-31 17:27:4599 info.pid = base::GetProcId(iter->handle());
[email protected]a27a9382009-02-11 23:55:10100 if (!info.pid)
101 continue;
102
[email protected]a436d922009-02-13 23:16:42103 info.type = iter->type();
[email protected]fcf79352010-12-28 20:13:20104 info.renderer_type = iter->renderer_type();
[email protected]68b9e72b2011-08-05 23:08:22105 info.titles.push_back(iter->name());
[email protected]a27a9382009-02-11 23:55:10106 child_info.push_back(info);
initial.commit09911bf2008-07-26 23:55:29107 }
108
109 // Now go do expensive memory lookups from the file thread.
[email protected]f8b3ef82010-10-11 02:45:52110 BrowserThread::PostTask(
111 BrowserThread::FILE, FROM_HERE,
[email protected]24d69692011-10-21 18:26:51112 base::Bind(&MemoryDetails::CollectProcessData, this, child_info));
initial.commit09911bf2008-07-26 23:55:29113}
114
[email protected]a27a9382009-02-11 23:55:10115void MemoryDetails::CollectChildInfoOnUIThread() {
[email protected]f8b3ef82010-10-11 02:45:52116 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
initial.commit09911bf2008-07-26 23:55:29117
[email protected]1fd5302c2011-05-28 04:06:43118#if defined(OS_POSIX) && !defined(OS_MACOSX)
[email protected]d3c6c0d72010-12-09 08:15:04119 const pid_t zygote_pid = ZygoteHost::GetInstance()->pid();
120 const pid_t sandbox_helper_pid = RenderSandboxHostLinux::GetInstance()->pid();
[email protected]54fd1d32009-09-01 00:12:58121#endif
122
123 ProcessData* const chrome_browser = ChromeBrowser();
[email protected]a27a9382009-02-11 23:55:10124 // Get more information about the process.
[email protected]54fd1d32009-09-01 00:12:58125 for (size_t index = 0; index < chrome_browser->processes.size();
initial.commit09911bf2008-07-26 23:55:29126 index++) {
[email protected]a27a9382009-02-11 23:55:10127 // Check if it's a renderer, if so get the list of page titles in it and
[email protected]fcf79352010-12-28 20:13:20128 // check if it's a diagnostics-related process. We skip about:memory pages.
129 // Iterate the RenderProcessHosts to find the tab contents.
[email protected]54fd1d32009-09-01 00:12:58130 ProcessMemoryInformation& process =
131 chrome_browser->processes[index];
132
[email protected]019191a2009-10-02 20:37:27133 for (RenderProcessHost::iterator renderer_iter(
134 RenderProcessHost::AllHostsIterator()); !renderer_iter.IsAtEnd();
135 renderer_iter.Advance()) {
[email protected]fcf79352010-12-28 20:13:20136 RenderProcessHost* render_process_host = renderer_iter.GetCurrentValue();
137 DCHECK(render_process_host);
[email protected]8a34e6602010-10-02 17:29:43138 // Ignore processes that don't have a connection, such as crashed tabs.
[email protected]fcf79352010-12-28 20:13:20139 if (!render_process_host->HasConnection() ||
140 process.pid != base::GetProcId(render_process_host->GetHandle())) {
[email protected]a27a9382009-02-11 23:55:10141 continue;
[email protected]201b2732009-11-13 18:57:46142 }
[email protected]a27a9382009-02-11 23:55:10143 process.type = ChildProcessInfo::RENDER_PROCESS;
[email protected]9b62ecf2011-07-27 20:23:08144 Profile* profile =
145 Profile::FromBrowserContext(render_process_host->browser_context());
[email protected]79dc42cd2011-01-08 21:43:35146 ExtensionService* extension_service = profile->GetExtensionService();
[email protected]8add5412011-10-01 21:02:14147 ExtensionProcessManager* extension_process_manager =
148 profile->GetExtensionProcessManager();
[email protected]79dc42cd2011-01-08 21:43:35149
[email protected]a27a9382009-02-11 23:55:10150 // The RenderProcessHost may host multiple TabContents. Any
151 // of them which contain diagnostics information make the whole
152 // process be considered a diagnostics process.
153 //
154 // NOTE: This is a bit dangerous. We know that for now, listeners
155 // are always RenderWidgetHosts. But in theory, they don't
156 // have to be.
[email protected]9de09f82009-08-17 20:13:53157 RenderProcessHost::listeners_iterator iter(
[email protected]fcf79352010-12-28 20:13:20158 render_process_host->ListenersIterator());
[email protected]9de09f82009-08-17 20:13:53159 for (; !iter.IsAtEnd(); iter.Advance()) {
160 const RenderWidgetHost* widget =
161 static_cast<const RenderWidgetHost*>(iter.GetCurrentValue());
[email protected]a27a9382009-02-11 23:55:10162 DCHECK(widget);
163 if (!widget || !widget->IsRenderView())
164 continue;
initial.commit09911bf2008-07-26 23:55:29165
[email protected]9de09f82009-08-17 20:13:53166 const RenderViewHost* host = static_cast<const RenderViewHost*>(widget);
[email protected]fcf79352010-12-28 20:13:20167 RenderViewHostDelegate* host_delegate = host->delegate();
[email protected]4e6ffde2011-03-11 00:59:27168 DCHECK(host_delegate);
[email protected]fcf79352010-12-28 20:13:20169 GURL url = host_delegate->GetURL();
[email protected]da4dfc42011-10-12 15:53:56170 content::ViewType type = host_delegate->GetRenderViewType();
[email protected]e091df82011-10-11 18:13:21171 if (host->enabled_bindings() & content::BINDINGS_POLICY_WEB_UI) {
[email protected]fcf79352010-12-28 20:13:20172 // TODO(erikkay) the type for devtools doesn't actually appear to
173 // be set.
[email protected]da4dfc42011-10-12 15:53:56174 if (type == content::VIEW_TYPE_DEV_TOOLS_UI)
[email protected]fcf79352010-12-28 20:13:20175 process.renderer_type = ChildProcessInfo::RENDERER_DEVTOOLS;
176 else
177 process.renderer_type = ChildProcessInfo::RENDERER_CHROME;
[email protected]8add5412011-10-01 21:02:14178 } else if (extension_process_manager->AreBindingsEnabledForProcess(
179 host->process()->id())) {
[email protected]fcf79352010-12-28 20:13:20180 process.renderer_type = ChildProcessInfo::RENDERER_EXTENSION;
181 }
[email protected]4e6ffde2011-03-11 00:59:27182 TabContents* contents = host_delegate->GetAsTabContents();
[email protected]fcf79352010-12-28 20:13:20183 if (!contents) {
[email protected]718eab62011-10-05 21:16:52184 if (extension_process_manager->IsExtensionProcess(
185 host->process()->id())) {
[email protected]79dc42cd2011-01-08 21:43:35186 const Extension* extension =
187 extension_service->GetExtensionByURL(url);
188 if (extension) {
189 string16 title = UTF8ToUTF16(extension->name());
190 process.titles.push_back(title);
191 }
[email protected]fcf79352010-12-28 20:13:20192 } else if (process.renderer_type ==
193 ChildProcessInfo::RENDERER_UNKNOWN) {
194 process.titles.push_back(UTF8ToUTF16(url.spec()));
195 switch (type) {
[email protected]da4dfc42011-10-12 15:53:56196 case chrome::VIEW_TYPE_BACKGROUND_CONTENTS:
[email protected]fcf79352010-12-28 20:13:20197 process.renderer_type =
198 ChildProcessInfo::RENDERER_BACKGROUND_APP;
199 break;
[email protected]da4dfc42011-10-12 15:53:56200 case content::VIEW_TYPE_INTERSTITIAL_PAGE:
[email protected]fcf79352010-12-28 20:13:20201 process.renderer_type = ChildProcessInfo::RENDERER_INTERSTITIAL;
202 break;
[email protected]da4dfc42011-10-12 15:53:56203 case chrome::VIEW_TYPE_NOTIFICATION:
[email protected]fcf79352010-12-28 20:13:20204 process.renderer_type = ChildProcessInfo::RENDERER_NOTIFICATION;
205 break;
206 default:
207 process.renderer_type = ChildProcessInfo::RENDERER_UNKNOWN;
208 break;
209 }
210 }
[email protected]a27a9382009-02-11 23:55:10211 continue;
[email protected]fcf79352010-12-28 20:13:20212 }
213
214 // Since We have a TabContents and and the renderer type hasn't been
215 // set yet, it must be a normal tabbed renderer.
216 if (process.renderer_type == ChildProcessInfo::RENDERER_UNKNOWN)
217 process.renderer_type = ChildProcessInfo::RENDERER_NORMAL;
218
[email protected]4f260d02010-12-23 18:35:42219 string16 title = contents->GetTitle();
[email protected]a27a9382009-02-11 23:55:10220 if (!title.length())
[email protected]4f260d02010-12-23 18:35:42221 title = l10n_util::GetStringUTF16(IDS_DEFAULT_TAB_TITLE);
[email protected]a27a9382009-02-11 23:55:10222 process.titles.push_back(title);
[email protected]cd3d7892009-03-04 23:55:06223
[email protected]ebe89e062009-08-13 23:16:54224 // We need to check the pending entry as well as the virtual_url to
[email protected]37ae3f22011-07-12 03:56:14225 // see if it's a chrome://memory URL (we don't want to count these in
226 // the total memory usage of the browser).
[email protected]cd3d7892009-03-04 23:55:06227 //
[email protected]37ae3f22011-07-12 03:56:14228 // When we reach here, chrome://memory will be the pending entry since
229 // we haven't responded with any data such that it would be committed.
230 // If you have another chrome://memory tab open (which would be
231 // committed), we don't want to count it either, so we also check the
232 // last committed entry.
[email protected]cd3d7892009-03-04 23:55:06233 //
234 // Either the pending or last committed entries can be NULL.
[email protected]6df40742009-03-19 22:24:50235 const NavigationEntry* pending_entry =
[email protected]ce3fa3c2009-04-20 19:55:57236 contents->controller().pending_entry();
[email protected]cd3d7892009-03-04 23:55:06237 const NavigationEntry* last_committed_entry =
[email protected]ce3fa3c2009-04-20 19:55:57238 contents->controller().GetLastCommittedEntry();
[email protected]cd3d7892009-03-04 23:55:06239 if ((last_committed_entry &&
[email protected]ebe89e062009-08-13 23:16:54240 LowerCaseEqualsASCII(last_committed_entry->virtual_url().spec(),
[email protected]37ae3f22011-07-12 03:56:14241 chrome::kChromeUIMemoryURL)) ||
[email protected]cd3d7892009-03-04 23:55:06242 (pending_entry &&
[email protected]ebe89e062009-08-13 23:16:54243 LowerCaseEqualsASCII(pending_entry->virtual_url().spec(),
[email protected]37ae3f22011-07-12 03:56:14244 chrome::kChromeUIMemoryURL)))
[email protected]a27a9382009-02-11 23:55:10245 process.is_diagnostics = true;
initial.commit09911bf2008-07-26 23:55:29246 }
247 }
[email protected]54fd1d32009-09-01 00:12:58248
[email protected]1fd5302c2011-05-28 04:06:43249#if defined(OS_POSIX) && !defined(OS_MACOSX)
[email protected]54fd1d32009-09-01 00:12:58250 if (process.pid == zygote_pid) {
251 process.type = ChildProcessInfo::ZYGOTE_PROCESS;
252 } else if (process.pid == sandbox_helper_pid) {
253 process.type = ChildProcessInfo::SANDBOX_HELPER_PROCESS;
254 }
255#endif
initial.commit09911bf2008-07-26 23:55:29256 }
257
[email protected]a27a9382009-02-11 23:55:10258 // Get rid of other Chrome processes that are from a different profile.
[email protected]54fd1d32009-09-01 00:12:58259 for (size_t index = 0; index < chrome_browser->processes.size();
[email protected]a27a9382009-02-11 23:55:10260 index++) {
[email protected]54fd1d32009-09-01 00:12:58261 if (chrome_browser->processes[index].type ==
[email protected]a27a9382009-02-11 23:55:10262 ChildProcessInfo::UNKNOWN_PROCESS) {
[email protected]54fd1d32009-09-01 00:12:58263 chrome_browser->processes.erase(
264 chrome_browser->processes.begin() + index);
[email protected]a436d922009-02-13 23:16:42265 index--;
[email protected]a27a9382009-02-11 23:55:10266 }
267 }
268
initial.commit09911bf2008-07-26 23:55:29269 UpdateHistograms();
270
271 OnDetailsAvailable();
272}
273
274void MemoryDetails::UpdateHistograms() {
275 // Reports a set of memory metrics to UMA.
[email protected]57c4b852009-08-17 21:59:29276 // Memory is measured in KB.
initial.commit09911bf2008-07-26 23:55:29277
[email protected]54fd1d32009-09-01 00:12:58278 const ProcessData& browser = *ChromeBrowser();
initial.commit09911bf2008-07-26 23:55:29279 size_t aggregate_memory = 0;
[email protected]fcf79352010-12-28 20:13:20280 int chrome_count = 0;
281 int extension_count = 0;
[email protected]a27a9382009-02-11 23:55:10282 int plugin_count = 0;
[email protected]eef348fb2011-08-01 21:11:08283 int pepper_plugin_count = 0;
[email protected]fcf79352010-12-28 20:13:20284 int renderer_count = 0;
285 int other_count = 0;
[email protected]a27a9382009-02-11 23:55:10286 int worker_count = 0;
initial.commit09911bf2008-07-26 23:55:29287 for (size_t index = 0; index < browser.processes.size(); index++) {
[email protected]921cd0cc2008-10-21 22:30:55288 int sample = static_cast<int>(browser.processes[index].working_set.priv);
289 aggregate_memory += sample;
[email protected]a27a9382009-02-11 23:55:10290 switch (browser.processes[index].type) {
[email protected]f164cea2009-11-05 23:37:40291 case ChildProcessInfo::BROWSER_PROCESS:
292 UMA_HISTOGRAM_MEMORY_KB("Memory.Browser", sample);
293 break;
[email protected]fcf79352010-12-28 20:13:20294 case ChildProcessInfo::RENDER_PROCESS: {
295 ChildProcessInfo::RendererProcessType renderer_type =
296 browser.processes[index].renderer_type;
297 switch (renderer_type) {
298 case ChildProcessInfo::RENDERER_EXTENSION:
299 UMA_HISTOGRAM_MEMORY_KB("Memory.Extension", sample);
300 extension_count++;
301 break;
302 case ChildProcessInfo::RENDERER_CHROME:
303 UMA_HISTOGRAM_MEMORY_KB("Memory.Chrome", sample);
304 chrome_count++;
305 break;
306 case ChildProcessInfo::RENDERER_UNKNOWN:
307 NOTREACHED() << "Unknown renderer process type.";
308 break;
309 case ChildProcessInfo::RENDERER_NORMAL:
310 default:
311 // TODO(erikkay): Should we bother splitting out the other subtypes?
312 UMA_HISTOGRAM_MEMORY_KB("Memory.Renderer", sample);
313 renderer_count++;
314 break;
315 }
[email protected]f164cea2009-11-05 23:37:40316 break;
[email protected]fcf79352010-12-28 20:13:20317 }
[email protected]f164cea2009-11-05 23:37:40318 case ChildProcessInfo::PLUGIN_PROCESS:
319 UMA_HISTOGRAM_MEMORY_KB("Memory.Plugin", sample);
320 plugin_count++;
321 break;
322 case ChildProcessInfo::WORKER_PROCESS:
323 UMA_HISTOGRAM_MEMORY_KB("Memory.Worker", sample);
324 worker_count++;
325 break;
326 case ChildProcessInfo::UTILITY_PROCESS:
327 UMA_HISTOGRAM_MEMORY_KB("Memory.Utility", sample);
[email protected]fcf79352010-12-28 20:13:20328 other_count++;
[email protected]f164cea2009-11-05 23:37:40329 break;
330 case ChildProcessInfo::ZYGOTE_PROCESS:
331 UMA_HISTOGRAM_MEMORY_KB("Memory.Zygote", sample);
[email protected]fcf79352010-12-28 20:13:20332 other_count++;
[email protected]f164cea2009-11-05 23:37:40333 break;
334 case ChildProcessInfo::SANDBOX_HELPER_PROCESS:
335 UMA_HISTOGRAM_MEMORY_KB("Memory.SandboxHelper", sample);
[email protected]fcf79352010-12-28 20:13:20336 other_count++;
[email protected]f164cea2009-11-05 23:37:40337 break;
[email protected]103607e2010-02-01 18:57:09338 case ChildProcessInfo::NACL_LOADER_PROCESS:
[email protected]f164cea2009-11-05 23:37:40339 UMA_HISTOGRAM_MEMORY_KB("Memory.NativeClient", sample);
[email protected]fcf79352010-12-28 20:13:20340 other_count++;
[email protected]f164cea2009-11-05 23:37:40341 break;
[email protected]aef8d5ae2010-03-17 22:40:52342 case ChildProcessInfo::NACL_BROKER_PROCESS:
343 UMA_HISTOGRAM_MEMORY_KB("Memory.NativeClientBroker", sample);
[email protected]fcf79352010-12-28 20:13:20344 other_count++;
[email protected]aef8d5ae2010-03-17 22:40:52345 break;
[email protected]96fcbf2d2010-08-03 16:10:27346 case ChildProcessInfo::GPU_PROCESS:
347 UMA_HISTOGRAM_MEMORY_KB("Memory.Gpu", sample);
[email protected]fcf79352010-12-28 20:13:20348 other_count++;
[email protected]96fcbf2d2010-08-03 16:10:27349 break;
[email protected]eef348fb2011-08-01 21:11:08350 case ChildProcessInfo::PPAPI_PLUGIN_PROCESS:
351 UMA_HISTOGRAM_MEMORY_KB("Memory.PepperPlugin", sample);
352 pepper_plugin_count++;
353 break;
[email protected]f164cea2009-11-05 23:37:40354 default:
355 NOTREACHED();
[email protected]eef348fb2011-08-01 21:11:08356 break;
initial.commit09911bf2008-07-26 23:55:29357 }
358 }
[email protected]57c4b852009-08-17 21:59:29359 UMA_HISTOGRAM_MEMORY_KB("Memory.BackingStore",
360 BackingStoreManager::MemorySize() / 1024);
[email protected]a27a9382009-02-11 23:55:10361
[email protected]553dba62009-02-24 19:08:23362 UMA_HISTOGRAM_COUNTS_100("Memory.ProcessCount",
initial.commit09911bf2008-07-26 23:55:29363 static_cast<int>(browser.processes.size()));
[email protected]fcf79352010-12-28 20:13:20364 UMA_HISTOGRAM_COUNTS_100("Memory.ChromeProcessCount", chrome_count);
365 UMA_HISTOGRAM_COUNTS_100("Memory.ExtensionProcessCount", extension_count);
366 UMA_HISTOGRAM_COUNTS_100("Memory.OtherProcessCount", other_count);
[email protected]553dba62009-02-24 19:08:23367 UMA_HISTOGRAM_COUNTS_100("Memory.PluginProcessCount", plugin_count);
[email protected]eef348fb2011-08-01 21:11:08368 UMA_HISTOGRAM_COUNTS_100("Memory.PepperPluginProcessCount",
369 pepper_plugin_count);
[email protected]fcf79352010-12-28 20:13:20370 UMA_HISTOGRAM_COUNTS_100("Memory.RendererProcessCount", renderer_count);
[email protected]553dba62009-02-24 19:08:23371 UMA_HISTOGRAM_COUNTS_100("Memory.WorkerProcessCount", worker_count);
[email protected]f164cea2009-11-05 23:37:40372 // TODO(viettrungluu): Do we want separate counts for the other
373 // (platform-specific) process types?
[email protected]921cd0cc2008-10-21 22:30:55374
375 int total_sample = static_cast<int>(aggregate_memory / 1000);
[email protected]553dba62009-02-24 19:08:23376 UMA_HISTOGRAM_MEMORY_MB("Memory.Total", total_sample);
initial.commit09911bf2008-07-26 23:55:29377}