blob: 3237eb7170514685bef44b0fac6b41432eb990ad [file] [log] [blame]
[email protected]b0b67cf2012-01-18 21:59:571// Copyright (c) 2012 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]14afc012011-12-01 01:04:3916#include "chrome/common/chrome_view_type.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]4967f792012-01-20 22:14:4019#include "content/public/browser/browser_child_process_host_iterator.h"
[email protected]c38831a12011-10-28 12:44:4920#include "content/public/browser/browser_thread.h"
[email protected]9c1662b2012-03-06 15:44:3321#include "content/public/browser/child_process_data.h"
[email protected]a53209b2012-01-20 16:48:1622#include "content/public/browser/navigation_controller.h"
[email protected]022af742011-12-28 18:37:2523#include "content/public/browser/navigation_entry.h"
[email protected]f3b1a082011-11-18 00:34:3024#include "content/public/browser/render_process_host.h"
[email protected]9c1662b2012-03-06 15:44:3325#include "content/public/browser/render_view_host.h"
[email protected]b0b67cf2012-01-18 21:59:5726#include "content/public/browser/render_view_host_delegate.h"
[email protected]83ff91c2012-01-05 20:54:1327#include "content/public/browser/web_contents.h"
[email protected]e091df82011-10-11 18:13:2128#include "content/public/common/bindings_policy.h"
[email protected]a54311142011-12-01 05:13:4129#include "content/public/common/process_type.h"
[email protected]ae5ca892009-07-30 18:00:4730#include "grit/chromium_strings.h"
[email protected]4f260d02010-12-23 18:35:4231#include "grit/generated_resources.h"
[email protected]c051a1b2011-01-21 23:30:1732#include "ui/base/l10n/l10n_util.h"
initial.commit09911bf2008-07-26 23:55:2933
[email protected]a423c9e2012-03-06 18:02:3134#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
[email protected]c2c68b1f2012-02-25 00:29:1535#include "content/public/browser/zygote_host_linux.h"
[email protected]54fd1d32009-09-01 00:12:5836#endif
initial.commit09911bf2008-07-26 23:55:2937
[email protected]4967f792012-01-20 22:14:4038using content::BrowserChildProcessHostIterator;
[email protected]631bb742011-11-02 11:29:3939using content::BrowserThread;
[email protected]10f417c52011-12-28 21:04:2340using content::NavigationEntry;
[email protected]eaabba22012-03-07 15:02:1141using content::RenderViewHost;
42using content::RenderWidgetHost;
[email protected]83ff91c2012-01-05 20:54:1343using content::WebContents;
[email protected]631bb742011-11-02 11:29:3944
[email protected]2c1978a2011-11-29 17:02:3945// static
46std::string ProcessMemoryInformation::GetRendererTypeNameInEnglish(
47 RendererProcessType type) {
48 switch (type) {
49 case RENDERER_NORMAL:
50 return "Tab";
51 case RENDERER_CHROME:
52 return "Tab (Chrome)";
53 case RENDERER_EXTENSION:
54 return "Extension";
55 case RENDERER_DEVTOOLS:
56 return "Devtools";
57 case RENDERER_INTERSTITIAL:
58 return "Interstitial";
59 case RENDERER_NOTIFICATION:
60 return "Notification";
61 case RENDERER_BACKGROUND_APP:
62 return "Background App";
63 case RENDERER_UNKNOWN:
64 default:
65 NOTREACHED() << "Unknown renderer process type!";
66 return "Unknown";
67 }
68}
69
70// static
71std::string ProcessMemoryInformation::GetFullTypeNameInEnglish(
[email protected]bd5d6cf2011-12-01 00:39:1272 content::ProcessType type,
[email protected]2c1978a2011-11-29 17:02:3973 RendererProcessType rtype) {
[email protected]bd5d6cf2011-12-01 00:39:1274 if (type == content::PROCESS_TYPE_RENDERER)
[email protected]2c1978a2011-11-29 17:02:3975 return GetRendererTypeNameInEnglish(rtype);
[email protected]a54311142011-12-01 05:13:4176 return content::GetProcessTypeNameInEnglish(type);
[email protected]2c1978a2011-11-29 17:02:3977}
78
[email protected]8e383412010-10-19 16:57:0379ProcessMemoryInformation::ProcessMemoryInformation()
80 : pid(0),
81 num_processes(0),
82 is_diagnostics(false),
[email protected]bd5d6cf2011-12-01 00:39:1283 type(content::PROCESS_TYPE_UNKNOWN),
[email protected]2c1978a2011-11-29 17:02:3984 renderer_type(RENDERER_UNKNOWN) {
[email protected]8e383412010-10-19 16:57:0385}
86
87ProcessMemoryInformation::~ProcessMemoryInformation() {}
88
[email protected]93aa89c72010-10-20 21:32:0489ProcessData::ProcessData() {}
90
91ProcessData::ProcessData(const ProcessData& rhs)
92 : name(rhs.name),
93 process_name(rhs.process_name),
94 processes(rhs.processes) {
95}
96
97ProcessData::~ProcessData() {}
98
99ProcessData& ProcessData::operator=(const ProcessData& rhs) {
100 name = rhs.name;
101 process_name = rhs.process_name;
102 processes = rhs.processes;
103 return *this;
104}
105
initial.commit09911bf2008-07-26 23:55:29106// About threading:
107//
108// This operation will hit no fewer than 3 threads.
109//
[email protected]a436d922009-02-13 23:16:42110// The ChildProcessInfo::Iterator can only be accessed from the IO thread.
initial.commit09911bf2008-07-26 23:55:29111//
112// The RenderProcessHostIterator can only be accessed from the UI thread.
113//
114// This operation can take 30-100ms to complete. We never want to have
115// one task run for that long on the UI or IO threads. So, we run the
116// expensive parts of this operation over on the file thread.
117//
initial.commit09911bf2008-07-26 23:55:29118void MemoryDetails::StartFetch() {
[email protected]9bb480ee2011-08-03 21:41:16119 // This might get called from the UI or FILE threads, but should not be
120 // getting called from the IO thread.
[email protected]f8b3ef82010-10-11 02:45:52121 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO));
initial.commit09911bf2008-07-26 23:55:29122
123 // In order to process this request, we need to use the plugin information.
124 // However, plugin process information is only available from the IO thread.
[email protected]f8b3ef82010-10-11 02:45:52125 BrowserThread::PostTask(
126 BrowserThread::IO, FROM_HERE,
[email protected]24d69692011-10-21 18:26:51127 base::Bind(&MemoryDetails::CollectChildInfoOnIOThread, this));
initial.commit09911bf2008-07-26 23:55:29128}
129
[email protected]8e383412010-10-19 16:57:03130MemoryDetails::~MemoryDetails() {}
131
[email protected]a27a9382009-02-11 23:55:10132void MemoryDetails::CollectChildInfoOnIOThread() {
[email protected]f8b3ef82010-10-11 02:45:52133 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
initial.commit09911bf2008-07-26 23:55:29134
[email protected]a27a9382009-02-11 23:55:10135 std::vector<ProcessMemoryInformation> child_info;
136
[email protected]a436d922009-02-13 23:16:42137 // Collect the list of child processes.
[email protected]4967f792012-01-20 22:14:40138 for (BrowserChildProcessHostIterator iter; !iter.Done(); ++iter) {
[email protected]a27a9382009-02-11 23:55:10139 ProcessMemoryInformation info;
[email protected]4967f792012-01-20 22:14:40140 info.pid = base::GetProcId(iter.GetData().handle);
[email protected]a27a9382009-02-11 23:55:10141 if (!info.pid)
142 continue;
143
[email protected]4967f792012-01-20 22:14:40144 info.type = iter.GetData().type;
[email protected]2c1978a2011-11-29 17:02:39145 info.renderer_type = ProcessMemoryInformation::RENDERER_UNKNOWN;
[email protected]4967f792012-01-20 22:14:40146 info.titles.push_back(iter.GetData().name);
[email protected]a27a9382009-02-11 23:55:10147 child_info.push_back(info);
initial.commit09911bf2008-07-26 23:55:29148 }
149
150 // Now go do expensive memory lookups from the file thread.
[email protected]f8b3ef82010-10-11 02:45:52151 BrowserThread::PostTask(
152 BrowserThread::FILE, FROM_HERE,
[email protected]24d69692011-10-21 18:26:51153 base::Bind(&MemoryDetails::CollectProcessData, this, child_info));
initial.commit09911bf2008-07-26 23:55:29154}
155
[email protected]a27a9382009-02-11 23:55:10156void MemoryDetails::CollectChildInfoOnUIThread() {
[email protected]f8b3ef82010-10-11 02:45:52157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
initial.commit09911bf2008-07-26 23:55:29158
[email protected]a423c9e2012-03-06 18:02:31159#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
[email protected]c2c68b1f2012-02-25 00:29:15160 const pid_t zygote_pid = content::ZygoteHost::GetInstance()->GetPid();
[email protected]52356d22012-02-29 18:34:20161 const pid_t sandbox_helper_pid =
162 content::ZygoteHost::GetInstance()->GetSandboxHelperPid();
[email protected]54fd1d32009-09-01 00:12:58163#endif
164
165 ProcessData* const chrome_browser = ChromeBrowser();
[email protected]a27a9382009-02-11 23:55:10166 // Get more information about the process.
[email protected]54fd1d32009-09-01 00:12:58167 for (size_t index = 0; index < chrome_browser->processes.size();
initial.commit09911bf2008-07-26 23:55:29168 index++) {
[email protected]a27a9382009-02-11 23:55:10169 // Check if it's a renderer, if so get the list of page titles in it and
[email protected]fcf79352010-12-28 20:13:20170 // check if it's a diagnostics-related process. We skip about:memory pages.
171 // Iterate the RenderProcessHosts to find the tab contents.
[email protected]54fd1d32009-09-01 00:12:58172 ProcessMemoryInformation& process =
173 chrome_browser->processes[index];
174
[email protected]f3b1a082011-11-18 00:34:30175 for (content::RenderProcessHost::iterator renderer_iter(
176 content::RenderProcessHost::AllHostsIterator());
177 !renderer_iter.IsAtEnd(); renderer_iter.Advance()) {
178 content::RenderProcessHost* render_process_host =
179 renderer_iter.GetCurrentValue();
[email protected]fcf79352010-12-28 20:13:20180 DCHECK(render_process_host);
[email protected]8a34e6602010-10-02 17:29:43181 // Ignore processes that don't have a connection, such as crashed tabs.
[email protected]fcf79352010-12-28 20:13:20182 if (!render_process_host->HasConnection() ||
183 process.pid != base::GetProcId(render_process_host->GetHandle())) {
[email protected]a27a9382009-02-11 23:55:10184 continue;
[email protected]201b2732009-11-13 18:57:46185 }
[email protected]bd5d6cf2011-12-01 00:39:12186 process.type = content::PROCESS_TYPE_RENDERER;
[email protected]9b62ecf2011-07-27 20:23:08187 Profile* profile =
[email protected]f3b1a082011-11-18 00:34:30188 Profile::FromBrowserContext(
189 render_process_host->GetBrowserContext());
[email protected]79dc42cd2011-01-08 21:43:35190 ExtensionService* extension_service = profile->GetExtensionService();
[email protected]6f371442011-11-09 06:45:46191 extensions::ProcessMap* extension_process_map =
192 extension_service->process_map();
[email protected]79dc42cd2011-01-08 21:43:35193
[email protected]a27a9382009-02-11 23:55:10194 // The RenderProcessHost may host multiple TabContents. Any
195 // of them which contain diagnostics information make the whole
196 // process be considered a diagnostics process.
197 //
198 // NOTE: This is a bit dangerous. We know that for now, listeners
199 // are always RenderWidgetHosts. But in theory, they don't
200 // have to be.
[email protected]f3b1a082011-11-18 00:34:30201 content::RenderProcessHost::listeners_iterator iter(
[email protected]fcf79352010-12-28 20:13:20202 render_process_host->ListenersIterator());
[email protected]9de09f82009-08-17 20:13:53203 for (; !iter.IsAtEnd(); iter.Advance()) {
204 const RenderWidgetHost* widget =
[email protected]fd1ff072012-02-23 14:48:22205 RenderWidgetHost::FromIPCChannelListener(iter.GetCurrentValue());
[email protected]a27a9382009-02-11 23:55:10206 DCHECK(widget);
207 if (!widget || !widget->IsRenderView())
208 continue;
initial.commit09911bf2008-07-26 23:55:29209
[email protected]9c1662b2012-03-06 15:44:33210 const RenderViewHost* host =
211 RenderViewHost::From(const_cast<RenderWidgetHost*>(widget));
[email protected]9f76c1e2012-03-05 15:15:58212 content::RenderViewHostDelegate* host_delegate = host->GetDelegate();
[email protected]4e6ffde2011-03-11 00:59:27213 DCHECK(host_delegate);
[email protected]fcf79352010-12-28 20:13:20214 GURL url = host_delegate->GetURL();
[email protected]da4dfc42011-10-12 15:53:56215 content::ViewType type = host_delegate->GetRenderViewType();
[email protected]9f76c1e2012-03-05 15:15:58216 if (host->GetEnabledBindings() & content::BINDINGS_POLICY_WEB_UI) {
[email protected]fcf79352010-12-28 20:13:20217 // TODO(erikkay) the type for devtools doesn't actually appear to
218 // be set.
[email protected]da4dfc42011-10-12 15:53:56219 if (type == content::VIEW_TYPE_DEV_TOOLS_UI)
[email protected]2c1978a2011-11-29 17:02:39220 process.renderer_type = ProcessMemoryInformation::RENDERER_DEVTOOLS;
[email protected]fcf79352010-12-28 20:13:20221 else
[email protected]2c1978a2011-11-29 17:02:39222 process.renderer_type = ProcessMemoryInformation::RENDERER_CHROME;
[email protected]9f76c1e2012-03-05 15:15:58223 } else if (extension_process_map->Contains(
224 host->GetProcess()->GetID())) {
[email protected]6f371442011-11-09 06:45:46225 // For our purposes, don't count processes containing only hosted apps
226 // as extension processes. See also: crbug.com/102533.
227 std::set<std::string> extension_ids =
228 extension_process_map->GetExtensionsInProcess(
[email protected]9f76c1e2012-03-05 15:15:58229 host->GetProcess()->GetID());
[email protected]6f371442011-11-09 06:45:46230 for (std::set<std::string>::iterator iter = extension_ids.begin();
231 iter != extension_ids.end(); ++iter) {
232 const Extension* extension =
233 extension_service->GetExtensionById(*iter, false);
234 if (extension && !extension->is_hosted_app()) {
[email protected]2c1978a2011-11-29 17:02:39235 process.renderer_type =
236 ProcessMemoryInformation::RENDERER_EXTENSION;
[email protected]6f371442011-11-09 06:45:46237 break;
238 }
239 }
[email protected]fcf79352010-12-28 20:13:20240 }
[email protected]83ff91c2012-01-05 20:54:13241 WebContents* contents = host_delegate->GetAsWebContents();
[email protected]fcf79352010-12-28 20:13:20242 if (!contents) {
[email protected]9f76c1e2012-03-05 15:15:58243 if (extension_process_map->Contains(host->GetProcess()->GetID())) {
[email protected]79dc42cd2011-01-08 21:43:35244 const Extension* extension =
[email protected]615d88f2011-12-13 01:47:44245 extension_service->extensions()->GetByID(url.host());
[email protected]79dc42cd2011-01-08 21:43:35246 if (extension) {
247 string16 title = UTF8ToUTF16(extension->name());
248 process.titles.push_back(title);
249 }
[email protected]fcf79352010-12-28 20:13:20250 } else if (process.renderer_type ==
[email protected]2c1978a2011-11-29 17:02:39251 ProcessMemoryInformation::RENDERER_UNKNOWN) {
[email protected]fcf79352010-12-28 20:13:20252 process.titles.push_back(UTF8ToUTF16(url.spec()));
253 switch (type) {
[email protected]da4dfc42011-10-12 15:53:56254 case chrome::VIEW_TYPE_BACKGROUND_CONTENTS:
[email protected]fcf79352010-12-28 20:13:20255 process.renderer_type =
[email protected]2c1978a2011-11-29 17:02:39256 ProcessMemoryInformation::RENDERER_BACKGROUND_APP;
[email protected]fcf79352010-12-28 20:13:20257 break;
[email protected]da4dfc42011-10-12 15:53:56258 case content::VIEW_TYPE_INTERSTITIAL_PAGE:
[email protected]2c1978a2011-11-29 17:02:39259 process.renderer_type =
260 ProcessMemoryInformation::RENDERER_INTERSTITIAL;
[email protected]fcf79352010-12-28 20:13:20261 break;
[email protected]da4dfc42011-10-12 15:53:56262 case chrome::VIEW_TYPE_NOTIFICATION:
[email protected]2c1978a2011-11-29 17:02:39263 process.renderer_type =
264 ProcessMemoryInformation::RENDERER_NOTIFICATION;
[email protected]fcf79352010-12-28 20:13:20265 break;
266 default:
[email protected]2c1978a2011-11-29 17:02:39267 process.renderer_type =
268 ProcessMemoryInformation::RENDERER_UNKNOWN;
[email protected]fcf79352010-12-28 20:13:20269 break;
270 }
271 }
[email protected]a27a9382009-02-11 23:55:10272 continue;
[email protected]fcf79352010-12-28 20:13:20273 }
274
[email protected]83ff91c2012-01-05 20:54:13275 // Since We have a WebContents and and the renderer type hasn't been
[email protected]fcf79352010-12-28 20:13:20276 // set yet, it must be a normal tabbed renderer.
[email protected]2c1978a2011-11-29 17:02:39277 if (process.renderer_type == ProcessMemoryInformation::RENDERER_UNKNOWN)
278 process.renderer_type = ProcessMemoryInformation::RENDERER_NORMAL;
[email protected]fcf79352010-12-28 20:13:20279
[email protected]4f260d02010-12-23 18:35:42280 string16 title = contents->GetTitle();
[email protected]a27a9382009-02-11 23:55:10281 if (!title.length())
[email protected]4f260d02010-12-23 18:35:42282 title = l10n_util::GetStringUTF16(IDS_DEFAULT_TAB_TITLE);
[email protected]a27a9382009-02-11 23:55:10283 process.titles.push_back(title);
[email protected]cd3d7892009-03-04 23:55:06284
[email protected]ebe89e062009-08-13 23:16:54285 // We need to check the pending entry as well as the virtual_url to
[email protected]37ae3f22011-07-12 03:56:14286 // see if it's a chrome://memory URL (we don't want to count these in
287 // the total memory usage of the browser).
[email protected]cd3d7892009-03-04 23:55:06288 //
[email protected]37ae3f22011-07-12 03:56:14289 // When we reach here, chrome://memory will be the pending entry since
290 // we haven't responded with any data such that it would be committed.
291 // If you have another chrome://memory tab open (which would be
292 // committed), we don't want to count it either, so we also check the
293 // last committed entry.
[email protected]cd3d7892009-03-04 23:55:06294 //
295 // Either the pending or last committed entries can be NULL.
[email protected]10f417c52011-12-28 21:04:23296 const NavigationEntry* pending_entry =
[email protected]022af742011-12-28 18:37:25297 contents->GetController().GetPendingEntry();
[email protected]10f417c52011-12-28 21:04:23298 const NavigationEntry* last_committed_entry =
[email protected]f5fa20e2011-12-21 22:35:56299 contents->GetController().GetLastCommittedEntry();
[email protected]cd3d7892009-03-04 23:55:06300 if ((last_committed_entry &&
[email protected]36fc0392011-12-25 03:59:51301 LowerCaseEqualsASCII(last_committed_entry->GetVirtualURL().spec(),
[email protected]37ae3f22011-07-12 03:56:14302 chrome::kChromeUIMemoryURL)) ||
[email protected]cd3d7892009-03-04 23:55:06303 (pending_entry &&
[email protected]36fc0392011-12-25 03:59:51304 LowerCaseEqualsASCII(pending_entry->GetVirtualURL().spec(),
[email protected]37ae3f22011-07-12 03:56:14305 chrome::kChromeUIMemoryURL)))
[email protected]a27a9382009-02-11 23:55:10306 process.is_diagnostics = true;
initial.commit09911bf2008-07-26 23:55:29307 }
308 }
[email protected]54fd1d32009-09-01 00:12:58309
[email protected]a423c9e2012-03-06 18:02:31310#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
[email protected]54fd1d32009-09-01 00:12:58311 if (process.pid == zygote_pid) {
[email protected]bd5d6cf2011-12-01 00:39:12312 process.type = content::PROCESS_TYPE_ZYGOTE;
[email protected]54fd1d32009-09-01 00:12:58313 } else if (process.pid == sandbox_helper_pid) {
[email protected]bd5d6cf2011-12-01 00:39:12314 process.type = content::PROCESS_TYPE_SANDBOX_HELPER;
[email protected]54fd1d32009-09-01 00:12:58315 }
316#endif
initial.commit09911bf2008-07-26 23:55:29317 }
318
[email protected]a27a9382009-02-11 23:55:10319 // Get rid of other Chrome processes that are from a different profile.
[email protected]54fd1d32009-09-01 00:12:58320 for (size_t index = 0; index < chrome_browser->processes.size();
[email protected]a27a9382009-02-11 23:55:10321 index++) {
[email protected]54fd1d32009-09-01 00:12:58322 if (chrome_browser->processes[index].type ==
[email protected]bd5d6cf2011-12-01 00:39:12323 content::PROCESS_TYPE_UNKNOWN) {
[email protected]54fd1d32009-09-01 00:12:58324 chrome_browser->processes.erase(
325 chrome_browser->processes.begin() + index);
[email protected]a436d922009-02-13 23:16:42326 index--;
[email protected]a27a9382009-02-11 23:55:10327 }
328 }
329
initial.commit09911bf2008-07-26 23:55:29330 UpdateHistograms();
331
332 OnDetailsAvailable();
333}
334
335void MemoryDetails::UpdateHistograms() {
336 // Reports a set of memory metrics to UMA.
[email protected]57c4b852009-08-17 21:59:29337 // Memory is measured in KB.
initial.commit09911bf2008-07-26 23:55:29338
[email protected]54fd1d32009-09-01 00:12:58339 const ProcessData& browser = *ChromeBrowser();
initial.commit09911bf2008-07-26 23:55:29340 size_t aggregate_memory = 0;
[email protected]fcf79352010-12-28 20:13:20341 int chrome_count = 0;
342 int extension_count = 0;
[email protected]a27a9382009-02-11 23:55:10343 int plugin_count = 0;
[email protected]eef348fb2011-08-01 21:11:08344 int pepper_plugin_count = 0;
[email protected]fcf79352010-12-28 20:13:20345 int renderer_count = 0;
346 int other_count = 0;
[email protected]a27a9382009-02-11 23:55:10347 int worker_count = 0;
initial.commit09911bf2008-07-26 23:55:29348 for (size_t index = 0; index < browser.processes.size(); index++) {
[email protected]921cd0cc2008-10-21 22:30:55349 int sample = static_cast<int>(browser.processes[index].working_set.priv);
350 aggregate_memory += sample;
[email protected]a27a9382009-02-11 23:55:10351 switch (browser.processes[index].type) {
[email protected]bd5d6cf2011-12-01 00:39:12352 case content::PROCESS_TYPE_BROWSER:
[email protected]f164cea2009-11-05 23:37:40353 UMA_HISTOGRAM_MEMORY_KB("Memory.Browser", sample);
354 break;
[email protected]bd5d6cf2011-12-01 00:39:12355 case content::PROCESS_TYPE_RENDERER: {
[email protected]2c1978a2011-11-29 17:02:39356 ProcessMemoryInformation::RendererProcessType renderer_type =
[email protected]fcf79352010-12-28 20:13:20357 browser.processes[index].renderer_type;
358 switch (renderer_type) {
[email protected]2c1978a2011-11-29 17:02:39359 case ProcessMemoryInformation::RENDERER_EXTENSION:
[email protected]fcf79352010-12-28 20:13:20360 UMA_HISTOGRAM_MEMORY_KB("Memory.Extension", sample);
361 extension_count++;
362 break;
[email protected]2c1978a2011-11-29 17:02:39363 case ProcessMemoryInformation::RENDERER_CHROME:
[email protected]fcf79352010-12-28 20:13:20364 UMA_HISTOGRAM_MEMORY_KB("Memory.Chrome", sample);
365 chrome_count++;
366 break;
[email protected]2c1978a2011-11-29 17:02:39367 case ProcessMemoryInformation::RENDERER_UNKNOWN:
[email protected]fcf79352010-12-28 20:13:20368 NOTREACHED() << "Unknown renderer process type.";
369 break;
[email protected]2c1978a2011-11-29 17:02:39370 case ProcessMemoryInformation::RENDERER_NORMAL:
[email protected]fcf79352010-12-28 20:13:20371 default:
372 // TODO(erikkay): Should we bother splitting out the other subtypes?
373 UMA_HISTOGRAM_MEMORY_KB("Memory.Renderer", sample);
374 renderer_count++;
375 break;
376 }
[email protected]f164cea2009-11-05 23:37:40377 break;
[email protected]fcf79352010-12-28 20:13:20378 }
[email protected]bd5d6cf2011-12-01 00:39:12379 case content::PROCESS_TYPE_PLUGIN:
[email protected]f164cea2009-11-05 23:37:40380 UMA_HISTOGRAM_MEMORY_KB("Memory.Plugin", sample);
381 plugin_count++;
382 break;
[email protected]bd5d6cf2011-12-01 00:39:12383 case content::PROCESS_TYPE_WORKER:
[email protected]f164cea2009-11-05 23:37:40384 UMA_HISTOGRAM_MEMORY_KB("Memory.Worker", sample);
385 worker_count++;
386 break;
[email protected]bd5d6cf2011-12-01 00:39:12387 case content::PROCESS_TYPE_UTILITY:
[email protected]f164cea2009-11-05 23:37:40388 UMA_HISTOGRAM_MEMORY_KB("Memory.Utility", sample);
[email protected]fcf79352010-12-28 20:13:20389 other_count++;
[email protected]f164cea2009-11-05 23:37:40390 break;
[email protected]bd5d6cf2011-12-01 00:39:12391 case content::PROCESS_TYPE_ZYGOTE:
[email protected]f164cea2009-11-05 23:37:40392 UMA_HISTOGRAM_MEMORY_KB("Memory.Zygote", sample);
[email protected]fcf79352010-12-28 20:13:20393 other_count++;
[email protected]f164cea2009-11-05 23:37:40394 break;
[email protected]bd5d6cf2011-12-01 00:39:12395 case content::PROCESS_TYPE_SANDBOX_HELPER:
[email protected]f164cea2009-11-05 23:37:40396 UMA_HISTOGRAM_MEMORY_KB("Memory.SandboxHelper", sample);
[email protected]fcf79352010-12-28 20:13:20397 other_count++;
[email protected]f164cea2009-11-05 23:37:40398 break;
[email protected]bd5d6cf2011-12-01 00:39:12399 case content::PROCESS_TYPE_NACL_LOADER:
[email protected]f164cea2009-11-05 23:37:40400 UMA_HISTOGRAM_MEMORY_KB("Memory.NativeClient", sample);
[email protected]fcf79352010-12-28 20:13:20401 other_count++;
[email protected]f164cea2009-11-05 23:37:40402 break;
[email protected]bd5d6cf2011-12-01 00:39:12403 case content::PROCESS_TYPE_NACL_BROKER:
[email protected]aef8d5ae2010-03-17 22:40:52404 UMA_HISTOGRAM_MEMORY_KB("Memory.NativeClientBroker", sample);
[email protected]fcf79352010-12-28 20:13:20405 other_count++;
[email protected]aef8d5ae2010-03-17 22:40:52406 break;
[email protected]bd5d6cf2011-12-01 00:39:12407 case content::PROCESS_TYPE_GPU:
[email protected]96fcbf2d2010-08-03 16:10:27408 UMA_HISTOGRAM_MEMORY_KB("Memory.Gpu", sample);
[email protected]fcf79352010-12-28 20:13:20409 other_count++;
[email protected]96fcbf2d2010-08-03 16:10:27410 break;
[email protected]bd5d6cf2011-12-01 00:39:12411 case content::PROCESS_TYPE_PPAPI_PLUGIN:
[email protected]eef348fb2011-08-01 21:11:08412 UMA_HISTOGRAM_MEMORY_KB("Memory.PepperPlugin", sample);
413 pepper_plugin_count++;
414 break;
[email protected]f164cea2009-11-05 23:37:40415 default:
416 NOTREACHED();
[email protected]eef348fb2011-08-01 21:11:08417 break;
initial.commit09911bf2008-07-26 23:55:29418 }
419 }
[email protected]57c4b852009-08-17 21:59:29420 UMA_HISTOGRAM_MEMORY_KB("Memory.BackingStore",
[email protected]0b07be452012-02-29 01:14:42421 RenderWidgetHost::BackingStoreMemorySize() / 1024);
[email protected]a27a9382009-02-11 23:55:10422
[email protected]553dba62009-02-24 19:08:23423 UMA_HISTOGRAM_COUNTS_100("Memory.ProcessCount",
initial.commit09911bf2008-07-26 23:55:29424 static_cast<int>(browser.processes.size()));
[email protected]fcf79352010-12-28 20:13:20425 UMA_HISTOGRAM_COUNTS_100("Memory.ChromeProcessCount", chrome_count);
426 UMA_HISTOGRAM_COUNTS_100("Memory.ExtensionProcessCount", extension_count);
427 UMA_HISTOGRAM_COUNTS_100("Memory.OtherProcessCount", other_count);
[email protected]553dba62009-02-24 19:08:23428 UMA_HISTOGRAM_COUNTS_100("Memory.PluginProcessCount", plugin_count);
[email protected]eef348fb2011-08-01 21:11:08429 UMA_HISTOGRAM_COUNTS_100("Memory.PepperPluginProcessCount",
430 pepper_plugin_count);
[email protected]fcf79352010-12-28 20:13:20431 UMA_HISTOGRAM_COUNTS_100("Memory.RendererProcessCount", renderer_count);
[email protected]553dba62009-02-24 19:08:23432 UMA_HISTOGRAM_COUNTS_100("Memory.WorkerProcessCount", worker_count);
[email protected]f164cea2009-11-05 23:37:40433 // TODO(viettrungluu): Do we want separate counts for the other
434 // (platform-specific) process types?
[email protected]921cd0cc2008-10-21 22:30:55435
436 int total_sample = static_cast<int>(aggregate_memory / 1000);
[email protected]553dba62009-02-24 19:08:23437 UMA_HISTOGRAM_MEMORY_MB("Memory.Total", total_sample);
initial.commit09911bf2008-07-26 23:55:29438}