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

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: added todo Created 9 years, 12 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/memory_details.h ('k') | chrome/browser/renderer_host/render_view_host.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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();
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 RenderViewHostDelegate* host_delegate = host->delegate();
154 GURL url = host_delegate->GetURL();
155 ViewType::Type type = host_delegate->GetRenderViewType();
156 if (host->enabled_bindings() & BindingsPolicy::DOM_UI) {
157 // TODO(erikkay) the type for devtools doesn't actually appear to
158 // be set.
159 if (type == ViewType::DEV_TOOLS_UI)
160 process.renderer_type = ChildProcessInfo::RENDERER_DEVTOOLS;
161 else
162 process.renderer_type = ChildProcessInfo::RENDERER_CHROME;
163 } else if (host->enabled_bindings() & BindingsPolicy::EXTENSION) {
164 process.renderer_type = ChildProcessInfo::RENDERER_EXTENSION;
165 }
149 TabContents* contents = NULL; 166 TabContents* contents = NULL;
150 if (host->delegate()) 167 if (host_delegate)
151 contents = host->delegate()->GetAsTabContents(); 168 contents = host_delegate->GetAsTabContents();
152 if (!contents) 169 if (!contents) {
170 if (host->is_extension_process()) {
171 // TODO(erikkay) should we just add GetAsExtensionHost to
172 // TabContents?
173 ExtensionHost* eh = static_cast<ExtensionHost*>(host_delegate);
174 string16 title = UTF8ToUTF16(eh->extension()->name());
175 process.titles.push_back(title);
176 } else if (process.renderer_type ==
177 ChildProcessInfo::RENDERER_UNKNOWN) {
178 switch (type) {
179 case ViewType::BACKGROUND_CONTENTS:
180 process.renderer_type =
181 ChildProcessInfo::RENDERER_BACKGROUND_APP;
182 break;
183 case ViewType::INTERSTITIAL_PAGE:
184 process.renderer_type = ChildProcessInfo::RENDERER_INTERSTITIAL;
185 process.titles.push_back(UTF8ToUTF16(url.spec()));
186 break;
187 case ViewType::NOTIFICATION:
188 process.renderer_type = ChildProcessInfo::RENDERER_NOTIFICATION;
189 break;
190 default:
191 process.renderer_type = ChildProcessInfo::RENDERER_UNKNOWN;
192 break;
193 }
194 }
153 continue; 195 continue;
196 }
197
198 if (process.renderer_type == ChildProcessInfo::RENDERER_UNKNOWN)
asargent_no_longer_on_chrome 2010/12/25 05:20:12 It's not obvious why you're converting unknown ren
Erik does not do reviews 2010/12/28 16:59:18 I added a comment.
199 process.renderer_type = ChildProcessInfo::RENDERER_NORMAL;
200
154 string16 title = contents->GetTitle(); 201 string16 title = contents->GetTitle();
155 if (!title.length()) 202 if (!title.length())
156 title = l10n_util::GetStringUTF16(IDS_DEFAULT_TAB_TITLE); 203 title = l10n_util::GetStringUTF16(IDS_DEFAULT_TAB_TITLE);
157 process.titles.push_back(title); 204 process.titles.push_back(title);
158 205
159 // We need to check the pending entry as well as the virtual_url to 206 // 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 207 // see if it's an about:memory URL (we don't want to count these in the
161 // total memory usage of the browser). 208 // total memory usage of the browser).
162 // 209 //
163 // When we reach here, about:memory will be the pending entry since we 210 // 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 252
206 OnDetailsAvailable(); 253 OnDetailsAvailable();
207 } 254 }
208 255
209 void MemoryDetails::UpdateHistograms() { 256 void MemoryDetails::UpdateHistograms() {
210 // Reports a set of memory metrics to UMA. 257 // Reports a set of memory metrics to UMA.
211 // Memory is measured in KB. 258 // Memory is measured in KB.
212 259
213 const ProcessData& browser = *ChromeBrowser(); 260 const ProcessData& browser = *ChromeBrowser();
214 size_t aggregate_memory = 0; 261 size_t aggregate_memory = 0;
262 int chrome_count = 0;
263 int extension_count = 0;
215 int plugin_count = 0; 264 int plugin_count = 0;
265 int renderer_count = 0;
266 int other_count = 0;
216 int worker_count = 0; 267 int worker_count = 0;
217 for (size_t index = 0; index < browser.processes.size(); index++) { 268 for (size_t index = 0; index < browser.processes.size(); index++) {
218 int sample = static_cast<int>(browser.processes[index].working_set.priv); 269 int sample = static_cast<int>(browser.processes[index].working_set.priv);
219 aggregate_memory += sample; 270 aggregate_memory += sample;
220 switch (browser.processes[index].type) { 271 switch (browser.processes[index].type) {
221 case ChildProcessInfo::BROWSER_PROCESS: 272 case ChildProcessInfo::BROWSER_PROCESS:
222 UMA_HISTOGRAM_MEMORY_KB("Memory.Browser", sample); 273 UMA_HISTOGRAM_MEMORY_KB("Memory.Browser", sample);
223 break; 274 break;
224 case ChildProcessInfo::RENDER_PROCESS: 275 case ChildProcessInfo::RENDER_PROCESS: {
225 UMA_HISTOGRAM_MEMORY_KB("Memory.Renderer", sample); 276 ChildProcessInfo::RendererProcessType renderer_type =
277 browser.processes[index].renderer_type;
278 switch (renderer_type) {
279 case ChildProcessInfo::RENDERER_EXTENSION:
280 UMA_HISTOGRAM_MEMORY_KB("Memory.Extension", sample);
281 extension_count++;
282 break;
283 case ChildProcessInfo::RENDERER_CHROME:
284 UMA_HISTOGRAM_MEMORY_KB("Memory.Chrome", sample);
285 chrome_count++;
286 break;
287 case ChildProcessInfo::RENDERER_NORMAL:
288 default:
289 // TODO(erikkay): Should we bother splitting out the other subtypes?
290 UMA_HISTOGRAM_MEMORY_KB("Memory.Renderer", sample);
291 renderer_count++;
292 break;
293 }
226 break; 294 break;
295 }
227 case ChildProcessInfo::PLUGIN_PROCESS: 296 case ChildProcessInfo::PLUGIN_PROCESS:
228 UMA_HISTOGRAM_MEMORY_KB("Memory.Plugin", sample); 297 UMA_HISTOGRAM_MEMORY_KB("Memory.Plugin", sample);
229 plugin_count++; 298 plugin_count++;
230 break; 299 break;
231 case ChildProcessInfo::WORKER_PROCESS: 300 case ChildProcessInfo::WORKER_PROCESS:
232 UMA_HISTOGRAM_MEMORY_KB("Memory.Worker", sample); 301 UMA_HISTOGRAM_MEMORY_KB("Memory.Worker", sample);
233 worker_count++; 302 worker_count++;
234 break; 303 break;
235 case ChildProcessInfo::UTILITY_PROCESS: 304 case ChildProcessInfo::UTILITY_PROCESS:
236 UMA_HISTOGRAM_MEMORY_KB("Memory.Utility", sample); 305 UMA_HISTOGRAM_MEMORY_KB("Memory.Utility", sample);
306 other_count++;
237 break; 307 break;
238 case ChildProcessInfo::ZYGOTE_PROCESS: 308 case ChildProcessInfo::ZYGOTE_PROCESS:
239 UMA_HISTOGRAM_MEMORY_KB("Memory.Zygote", sample); 309 UMA_HISTOGRAM_MEMORY_KB("Memory.Zygote", sample);
310 other_count++;
240 break; 311 break;
241 case ChildProcessInfo::SANDBOX_HELPER_PROCESS: 312 case ChildProcessInfo::SANDBOX_HELPER_PROCESS:
242 UMA_HISTOGRAM_MEMORY_KB("Memory.SandboxHelper", sample); 313 UMA_HISTOGRAM_MEMORY_KB("Memory.SandboxHelper", sample);
314 other_count++;
243 break; 315 break;
244 case ChildProcessInfo::NACL_LOADER_PROCESS: 316 case ChildProcessInfo::NACL_LOADER_PROCESS:
245 UMA_HISTOGRAM_MEMORY_KB("Memory.NativeClient", sample); 317 UMA_HISTOGRAM_MEMORY_KB("Memory.NativeClient", sample);
318 other_count++;
246 break; 319 break;
247 case ChildProcessInfo::NACL_BROKER_PROCESS: 320 case ChildProcessInfo::NACL_BROKER_PROCESS:
248 UMA_HISTOGRAM_MEMORY_KB("Memory.NativeClientBroker", sample); 321 UMA_HISTOGRAM_MEMORY_KB("Memory.NativeClientBroker", sample);
322 other_count++;
249 break; 323 break;
250 case ChildProcessInfo::GPU_PROCESS: 324 case ChildProcessInfo::GPU_PROCESS:
251 UMA_HISTOGRAM_MEMORY_KB("Memory.Gpu", sample); 325 UMA_HISTOGRAM_MEMORY_KB("Memory.Gpu", sample);
326 other_count++;
252 break; 327 break;
253 default: 328 default:
254 NOTREACHED(); 329 NOTREACHED();
255 } 330 }
256 } 331 }
257 UMA_HISTOGRAM_MEMORY_KB("Memory.BackingStore", 332 UMA_HISTOGRAM_MEMORY_KB("Memory.BackingStore",
258 BackingStoreManager::MemorySize() / 1024); 333 BackingStoreManager::MemorySize() / 1024);
259 334
260 UMA_HISTOGRAM_COUNTS_100("Memory.ProcessCount", 335 UMA_HISTOGRAM_COUNTS_100("Memory.ProcessCount",
261 static_cast<int>(browser.processes.size())); 336 static_cast<int>(browser.processes.size()));
337 UMA_HISTOGRAM_COUNTS_100("Memory.ChromeProcessCount", chrome_count);
338 UMA_HISTOGRAM_COUNTS_100("Memory.ExtensionProcessCount", extension_count);
339 UMA_HISTOGRAM_COUNTS_100("Memory.OtherProcessCount", other_count);
262 UMA_HISTOGRAM_COUNTS_100("Memory.PluginProcessCount", plugin_count); 340 UMA_HISTOGRAM_COUNTS_100("Memory.PluginProcessCount", plugin_count);
341 UMA_HISTOGRAM_COUNTS_100("Memory.RendererProcessCount", renderer_count);
263 UMA_HISTOGRAM_COUNTS_100("Memory.WorkerProcessCount", worker_count); 342 UMA_HISTOGRAM_COUNTS_100("Memory.WorkerProcessCount", worker_count);
264 // TODO(viettrungluu): Do we want separate counts for the other 343 // TODO(viettrungluu): Do we want separate counts for the other
265 // (platform-specific) process types? 344 // (platform-specific) process types?
266 345
267 int total_sample = static_cast<int>(aggregate_memory / 1000); 346 int total_sample = static_cast<int>(aggregate_memory / 1000);
268 UMA_HISTOGRAM_MEMORY_MB("Memory.Total", total_sample); 347 UMA_HISTOGRAM_MEMORY_MB("Memory.Total", total_sample);
269 } 348 }
OLDNEW
« no previous file with comments | « chrome/browser/memory_details.h ('k') | chrome/browser/renderer_host/render_view_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698