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

Side by Side Diff: chrome/browser/memory_details.cc

Issue 5981007: fix about:memory and memory histograms to show extensions more clearly (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 10 years 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/memory_details.h" 5 #include "chrome/browser/memory_details.h"
6 6
7 #include "app/l10n_util.h" 7 #include "app/l10n_util.h"
8 #include "base/file_version_info.h" 8 #include "base/file_version_info.h"
9 #include "base/metrics/histogram.h" 9 #include "base/metrics/histogram.h"
10 #include "base/process_util.h" 10 #include "base/process_util.h"
11 #include "base/string_util.h" 11 #include "base/string_util.h"
12 #include "base/utf_string_conversions.h" 12 #include "base/utf_string_conversions.h"
13 #include "chrome/browser/browser_child_process_host.h" 13 #include "chrome/browser/browser_child_process_host.h"
14 #include "chrome/browser/browser_thread.h" 14 #include "chrome/browser/browser_thread.h"
15 #include "chrome/browser/extensions/extension_host.h"
15 #include "chrome/browser/renderer_host/backing_store_manager.h" 16 #include "chrome/browser/renderer_host/backing_store_manager.h"
16 #include "chrome/browser/renderer_host/render_process_host.h" 17 #include "chrome/browser/renderer_host/render_process_host.h"
17 #include "chrome/browser/renderer_host/render_view_host.h" 18 #include "chrome/browser/renderer_host/render_view_host.h"
18 #include "chrome/browser/tab_contents/navigation_entry.h" 19 #include "chrome/browser/tab_contents/navigation_entry.h"
19 #include "chrome/browser/tab_contents/tab_contents.h" 20 #include "chrome/browser/tab_contents/tab_contents.h"
21 #include "chrome/common/bindings_policy.h"
22 #include "chrome/common/extensions/extension.h"
20 #include "chrome/common/url_constants.h" 23 #include "chrome/common/url_constants.h"
21 #include "grit/chromium_strings.h" 24 #include "grit/chromium_strings.h"
22 #include "grit/generated_resources.h" 25 #include "grit/generated_resources.h"
23 26
24 #if defined(OS_LINUX) 27 #if defined(OS_LINUX)
25 #include "chrome/browser/zygote_host_linux.h" 28 #include "chrome/browser/zygote_host_linux.h"
26 #include "chrome/browser/renderer_host/render_sandbox_host_linux.h" 29 #include "chrome/browser/renderer_host/render_sandbox_host_linux.h"
27 #endif 30 #endif
28 31
29 ProcessMemoryInformation::ProcessMemoryInformation() 32 ProcessMemoryInformation::ProcessMemoryInformation()
30 : pid(0), 33 : pid(0),
31 num_processes(0), 34 num_processes(0),
32 is_diagnostics(false), 35 is_diagnostics(false),
33 type(ChildProcessInfo::UNKNOWN_PROCESS) { 36 type(ChildProcessInfo::UNKNOWN_PROCESS),
37 renderer_type(ChildProcessInfo::RENDERER_UNKNOWN) {
34 } 38 }
35 39
36 ProcessMemoryInformation::~ProcessMemoryInformation() {} 40 ProcessMemoryInformation::~ProcessMemoryInformation() {}
37 41
38 ProcessData::ProcessData() {} 42 ProcessData::ProcessData() {}
39 43
40 ProcessData::ProcessData(const ProcessData& rhs) 44 ProcessData::ProcessData(const ProcessData& rhs)
41 : name(rhs.name), 45 : name(rhs.name),
42 process_name(rhs.process_name), 46 process_name(rhs.process_name),
43 processes(rhs.processes) { 47 processes(rhs.processes) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 std::vector<ProcessMemoryInformation> child_info; 87 std::vector<ProcessMemoryInformation> child_info;
84 88
85 // Collect the list of child processes. 89 // Collect the list of child processes.
86 for (BrowserChildProcessHost::Iterator iter; !iter.Done(); ++iter) { 90 for (BrowserChildProcessHost::Iterator iter; !iter.Done(); ++iter) {
87 ProcessMemoryInformation info; 91 ProcessMemoryInformation info;
88 info.pid = base::GetProcId(iter->handle()); 92 info.pid = base::GetProcId(iter->handle());
89 if (!info.pid) 93 if (!info.pid)
90 continue; 94 continue;
91 95
92 info.type = iter->type(); 96 info.type = iter->type();
97 info.renderer_type = iter->renderer_type();
93 info.titles.push_back(WideToUTF16Hack(iter->name())); 98 info.titles.push_back(WideToUTF16Hack(iter->name()));
94 child_info.push_back(info); 99 child_info.push_back(info);
95 } 100 }
96 101
97 // Now go do expensive memory lookups from the file thread. 102 // Now go do expensive memory lookups from the file thread.
98 BrowserThread::PostTask( 103 BrowserThread::PostTask(
99 BrowserThread::FILE, FROM_HERE, 104 BrowserThread::FILE, FROM_HERE,
100 NewRunnableMethod(this, &MemoryDetails::CollectProcessData, child_info)); 105 NewRunnableMethod(this, &MemoryDetails::CollectProcessData, child_info));
101 } 106 }
102 107
103 void MemoryDetails::CollectChildInfoOnUIThread() { 108 void MemoryDetails::CollectChildInfoOnUIThread() {
104 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 109 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
105 110
106 #if defined(OS_LINUX) 111 #if defined(OS_LINUX)
107 const pid_t zygote_pid = ZygoteHost::GetInstance()->pid(); 112 const pid_t zygote_pid = ZygoteHost::GetInstance()->pid();
108 const pid_t sandbox_helper_pid = RenderSandboxHostLinux::GetInstance()->pid(); 113 const pid_t sandbox_helper_pid = RenderSandboxHostLinux::GetInstance()->pid();
109 #endif 114 #endif
110 115
111 ProcessData* const chrome_browser = ChromeBrowser(); 116 ProcessData* const chrome_browser = ChromeBrowser();
112 // Get more information about the process. 117 // Get more information about the process.
113 for (size_t index = 0; index < chrome_browser->processes.size(); 118 for (size_t index = 0; index < chrome_browser->processes.size();
114 index++) { 119 index++) {
115 // Check if it's a renderer, if so get the list of page titles in it and 120 // Check if it's a renderer, if so get the list of page titles in it and
116 // check if it's a diagnostics-related process. We skip all diagnostics 121 // check if it's a diagnostics-related process. We skip about:memory pages.
117 // pages (e.g. "about:xxx" URLs). Iterate the RenderProcessHosts to find 122 // Iterate the RenderProcessHosts to find the tab contents.
118 // the tab contents.
119 ProcessMemoryInformation& process = 123 ProcessMemoryInformation& process =
120 chrome_browser->processes[index]; 124 chrome_browser->processes[index];
121 125
122 for (RenderProcessHost::iterator renderer_iter( 126 for (RenderProcessHost::iterator renderer_iter(
123 RenderProcessHost::AllHostsIterator()); !renderer_iter.IsAtEnd(); 127 RenderProcessHost::AllHostsIterator()); !renderer_iter.IsAtEnd();
124 renderer_iter.Advance()) { 128 renderer_iter.Advance()) {
125 DCHECK(renderer_iter.GetCurrentValue()); 129 RenderProcessHost* rph = renderer_iter.GetCurrentValue();
Mike Belshe 2010/12/24 00:50:53 nit: I have to think when I see "rph" as to what
Erik does not do reviews 2010/12/28 16:59:18 Done.
130 DCHECK(rph);
126 // Ignore processes that don't have a connection, such as crashed tabs. 131 // Ignore processes that don't have a connection, such as crashed tabs.
127 if (!renderer_iter.GetCurrentValue()->HasConnection() || process.pid != 132 if (!rph->HasConnection() ||
128 base::GetProcId(renderer_iter.GetCurrentValue()->GetHandle())) { 133 process.pid != base::GetProcId(rph->GetHandle())) {
129 continue; 134 continue;
130 } 135 }
131 process.type = ChildProcessInfo::RENDER_PROCESS; 136 process.type = ChildProcessInfo::RENDER_PROCESS;
132 // The RenderProcessHost may host multiple TabContents. Any 137 // The RenderProcessHost may host multiple TabContents. Any
133 // of them which contain diagnostics information make the whole 138 // of them which contain diagnostics information make the whole
134 // process be considered a diagnostics process. 139 // process be considered a diagnostics process.
135 // 140 //
136 // NOTE: This is a bit dangerous. We know that for now, listeners 141 // NOTE: This is a bit dangerous. We know that for now, listeners
137 // are always RenderWidgetHosts. But in theory, they don't 142 // are always RenderWidgetHosts. But in theory, they don't
138 // have to be. 143 // have to be.
139 RenderProcessHost::listeners_iterator iter( 144 RenderProcessHost::listeners_iterator iter(rph->ListenersIterator());
140 renderer_iter.GetCurrentValue()->ListenersIterator());
141 for (; !iter.IsAtEnd(); iter.Advance()) { 145 for (; !iter.IsAtEnd(); iter.Advance()) {
142 const RenderWidgetHost* widget = 146 const RenderWidgetHost* widget =
143 static_cast<const RenderWidgetHost*>(iter.GetCurrentValue()); 147 static_cast<const RenderWidgetHost*>(iter.GetCurrentValue());
144 DCHECK(widget); 148 DCHECK(widget);
145 if (!widget || !widget->IsRenderView()) 149 if (!widget || !widget->IsRenderView())
146 continue; 150 continue;
147 151
148 const RenderViewHost* host = static_cast<const RenderViewHost*>(widget); 152 const RenderViewHost* host = static_cast<const RenderViewHost*>(widget);
153 if (host->enabled_bindings() && BindingsPolicy::EXTENSION) {
154 process.renderer_type = ChildProcessInfo::RENDERER_EXTENSION;
155 } else if (host->enabled_bindings() && BindingsPolicy::DOM_UI) {
156 process.renderer_type = ChildProcessInfo::RENDERER_CHROME;
157 } else {
158 process.renderer_type = ChildProcessInfo::RENDERER_NORMAL;
159 }
149 TabContents* contents = NULL; 160 TabContents* contents = NULL;
150 if (host->delegate()) 161 if (host->delegate())
151 contents = host->delegate()->GetAsTabContents(); 162 contents = host->delegate()->GetAsTabContents();
152 if (!contents) 163 if (!contents) {
164 if (host->is_extension_process()) {
165 // TODO(erikkay) should we just add GetAsExtensionHost to
166 // TabContents?
167 ExtensionHost* eh = static_cast<ExtensionHost*>(host->delegate());
168 std::wstring title = UTF8ToWide(eh->extension()->name());
169 process.titles.push_back(title);
170 } else {
171 process.renderer_type = ChildProcessInfo::RENDERER_UNKNOWN;
172 }
153 continue; 173 continue;
174 }
175
154 string16 title = contents->GetTitle(); 176 string16 title = contents->GetTitle();
155 if (!title.length()) 177 if (!title.length())
156 title = l10n_util::GetStringUTF16(IDS_DEFAULT_TAB_TITLE); 178 title = l10n_util::GetStringUTF16(IDS_DEFAULT_TAB_TITLE);
157 process.titles.push_back(title); 179 process.titles.push_back(title);
158 180
159 // We need to check the pending entry as well as the virtual_url to 181 // We need to check the pending entry as well as the virtual_url to
160 // see if it's an about:memory URL (we don't want to count these in the 182 // see if it's an about:memory URL (we don't want to count these in the
161 // total memory usage of the browser). 183 // total memory usage of the browser).
162 // 184 //
163 // When we reach here, about:memory will be the pending entry since we 185 // When we reach here, about:memory will be the pending entry since we
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 227
206 OnDetailsAvailable(); 228 OnDetailsAvailable();
207 } 229 }
208 230
209 void MemoryDetails::UpdateHistograms() { 231 void MemoryDetails::UpdateHistograms() {
210 // Reports a set of memory metrics to UMA. 232 // Reports a set of memory metrics to UMA.
211 // Memory is measured in KB. 233 // Memory is measured in KB.
212 234
213 const ProcessData& browser = *ChromeBrowser(); 235 const ProcessData& browser = *ChromeBrowser();
214 size_t aggregate_memory = 0; 236 size_t aggregate_memory = 0;
237 int chrome_count = 0;
238 int extension_count = 0;
215 int plugin_count = 0; 239 int plugin_count = 0;
240 int renderer_count = 0;
241 int other_count = 0;
216 int worker_count = 0; 242 int worker_count = 0;
217 for (size_t index = 0; index < browser.processes.size(); index++) { 243 for (size_t index = 0; index < browser.processes.size(); index++) {
218 int sample = static_cast<int>(browser.processes[index].working_set.priv); 244 int sample = static_cast<int>(browser.processes[index].working_set.priv);
219 aggregate_memory += sample; 245 aggregate_memory += sample;
220 switch (browser.processes[index].type) { 246 switch (browser.processes[index].type) {
221 case ChildProcessInfo::BROWSER_PROCESS: 247 case ChildProcessInfo::BROWSER_PROCESS:
222 UMA_HISTOGRAM_MEMORY_KB("Memory.Browser", sample); 248 UMA_HISTOGRAM_MEMORY_KB("Memory.Browser", sample);
223 break; 249 break;
224 case ChildProcessInfo::RENDER_PROCESS: 250 case ChildProcessInfo::RENDER_PROCESS: {
225 UMA_HISTOGRAM_MEMORY_KB("Memory.Renderer", sample); 251 ChildProcessInfo::RendererProcessType renderer_type =
252 browser.processes[index].renderer_type;
253 switch (renderer_type) {
254 case ChildProcessInfo::RENDERER_EXTENSION:
255 UMA_HISTOGRAM_MEMORY_KB("Memory.Extension", sample);
256 extension_count++;
257 break;
258 case ChildProcessInfo::RENDERER_CHROME:
259 UMA_HISTOGRAM_MEMORY_KB("Memory.Chrome", sample);
260 chrome_count++;
261 break;
262 case ChildProcessInfo::RENDERER_UNKNOWN:
Mike Belshe 2010/12/24 00:50:53 should there be a DCHECK in the RENDERER_UNKNOWN c
Erik does not do reviews 2010/12/28 16:59:18 Done.
263 case ChildProcessInfo::RENDERER_NORMAL:
264 default:
265 UMA_HISTOGRAM_MEMORY_KB("Memory.Renderer", sample);
266 renderer_count++;
267 break;
268 }
226 break; 269 break;
270 }
227 case ChildProcessInfo::PLUGIN_PROCESS: 271 case ChildProcessInfo::PLUGIN_PROCESS:
228 UMA_HISTOGRAM_MEMORY_KB("Memory.Plugin", sample); 272 UMA_HISTOGRAM_MEMORY_KB("Memory.Plugin", sample);
229 plugin_count++; 273 plugin_count++;
230 break; 274 break;
231 case ChildProcessInfo::WORKER_PROCESS: 275 case ChildProcessInfo::WORKER_PROCESS:
232 UMA_HISTOGRAM_MEMORY_KB("Memory.Worker", sample); 276 UMA_HISTOGRAM_MEMORY_KB("Memory.Worker", sample);
233 worker_count++; 277 worker_count++;
234 break; 278 break;
235 case ChildProcessInfo::UTILITY_PROCESS: 279 case ChildProcessInfo::UTILITY_PROCESS:
236 UMA_HISTOGRAM_MEMORY_KB("Memory.Utility", sample); 280 UMA_HISTOGRAM_MEMORY_KB("Memory.Utility", sample);
281 other_count++;
237 break; 282 break;
238 case ChildProcessInfo::ZYGOTE_PROCESS: 283 case ChildProcessInfo::ZYGOTE_PROCESS:
239 UMA_HISTOGRAM_MEMORY_KB("Memory.Zygote", sample); 284 UMA_HISTOGRAM_MEMORY_KB("Memory.Zygote", sample);
285 other_count++;
240 break; 286 break;
241 case ChildProcessInfo::SANDBOX_HELPER_PROCESS: 287 case ChildProcessInfo::SANDBOX_HELPER_PROCESS:
242 UMA_HISTOGRAM_MEMORY_KB("Memory.SandboxHelper", sample); 288 UMA_HISTOGRAM_MEMORY_KB("Memory.SandboxHelper", sample);
289 other_count++;
243 break; 290 break;
244 case ChildProcessInfo::NACL_LOADER_PROCESS: 291 case ChildProcessInfo::NACL_LOADER_PROCESS:
245 UMA_HISTOGRAM_MEMORY_KB("Memory.NativeClient", sample); 292 UMA_HISTOGRAM_MEMORY_KB("Memory.NativeClient", sample);
293 other_count++;
246 break; 294 break;
247 case ChildProcessInfo::NACL_BROKER_PROCESS: 295 case ChildProcessInfo::NACL_BROKER_PROCESS:
248 UMA_HISTOGRAM_MEMORY_KB("Memory.NativeClientBroker", sample); 296 UMA_HISTOGRAM_MEMORY_KB("Memory.NativeClientBroker", sample);
297 other_count++;
249 break; 298 break;
250 case ChildProcessInfo::GPU_PROCESS: 299 case ChildProcessInfo::GPU_PROCESS:
251 UMA_HISTOGRAM_MEMORY_KB("Memory.Gpu", sample); 300 UMA_HISTOGRAM_MEMORY_KB("Memory.Gpu", sample);
301 other_count++;
252 break; 302 break;
253 default: 303 default:
254 NOTREACHED(); 304 NOTREACHED();
255 } 305 }
256 } 306 }
257 UMA_HISTOGRAM_MEMORY_KB("Memory.BackingStore", 307 UMA_HISTOGRAM_MEMORY_KB("Memory.BackingStore",
258 BackingStoreManager::MemorySize() / 1024); 308 BackingStoreManager::MemorySize() / 1024);
259 309
260 UMA_HISTOGRAM_COUNTS_100("Memory.ProcessCount", 310 UMA_HISTOGRAM_COUNTS_100("Memory.ProcessCount",
261 static_cast<int>(browser.processes.size())); 311 static_cast<int>(browser.processes.size()));
312 UMA_HISTOGRAM_COUNTS_100("Memory.ChromeProcessCount", chrome_count);
313 UMA_HISTOGRAM_COUNTS_100("Memory.ExtensionProcessCount", extension_count);
314 UMA_HISTOGRAM_COUNTS_100("Memory.OtherProcessCount", other_count);
262 UMA_HISTOGRAM_COUNTS_100("Memory.PluginProcessCount", plugin_count); 315 UMA_HISTOGRAM_COUNTS_100("Memory.PluginProcessCount", plugin_count);
316 UMA_HISTOGRAM_COUNTS_100("Memory.RendererProcessCount", renderer_count);
263 UMA_HISTOGRAM_COUNTS_100("Memory.WorkerProcessCount", worker_count); 317 UMA_HISTOGRAM_COUNTS_100("Memory.WorkerProcessCount", worker_count);
264 // TODO(viettrungluu): Do we want separate counts for the other 318 // TODO(viettrungluu): Do we want separate counts for the other
265 // (platform-specific) process types? 319 // (platform-specific) process types?
266 320
267 int total_sample = static_cast<int>(aggregate_memory / 1000); 321 int total_sample = static_cast<int>(aggregate_memory / 1000);
268 UMA_HISTOGRAM_MEMORY_MB("Memory.Total", total_sample); 322 UMA_HISTOGRAM_MEMORY_MB("Memory.Total", total_sample);
269 } 323 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698