OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "base/bind.h" | 7 #include "base/bind.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" |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 ProcessData* const chrome_browser = ChromeBrowser(); | 207 ProcessData* const chrome_browser = ChromeBrowser(); |
208 // Get more information about the process. | 208 // Get more information about the process. |
209 for (size_t index = 0; index < chrome_browser->processes.size(); | 209 for (size_t index = 0; index < chrome_browser->processes.size(); |
210 index++) { | 210 index++) { |
211 // Check if it's a renderer, if so get the list of page titles in it and | 211 // Check if it's a renderer, if so get the list of page titles in it and |
212 // check if it's a diagnostics-related process. We skip about:memory pages. | 212 // check if it's a diagnostics-related process. We skip about:memory pages. |
213 // Iterate the RenderProcessHosts to find the tab contents. | 213 // Iterate the RenderProcessHosts to find the tab contents. |
214 ProcessMemoryInformation& process = | 214 ProcessMemoryInformation& process = |
215 chrome_browser->processes[index]; | 215 chrome_browser->processes[index]; |
216 | 216 |
217 for (content::RenderProcessHost::iterator renderer_iter( | 217 RenderWidgetHost::List widgets = RenderWidgetHost::GetRenderWidgetHosts(); |
218 content::RenderProcessHost::AllHostsIterator()); | 218 for (size_t i = 0; i < widgets.size(); ++i) { |
219 !renderer_iter.IsAtEnd(); renderer_iter.Advance()) { | |
220 content::RenderProcessHost* render_process_host = | 219 content::RenderProcessHost* render_process_host = |
221 renderer_iter.GetCurrentValue(); | 220 widgets[i]->GetProcess(); |
222 DCHECK(render_process_host); | 221 DCHECK(render_process_host); |
223 // Ignore processes that don't have a connection, such as crashed tabs. | 222 // Ignore processes that don't have a connection, such as crashed tabs. |
224 if (!render_process_host->HasConnection() || | 223 if (!render_process_host->HasConnection() || |
225 process.pid != base::GetProcId(render_process_host->GetHandle())) { | 224 process.pid != base::GetProcId(render_process_host->GetHandle())) { |
226 continue; | 225 continue; |
227 } | 226 } |
228 process.process_type = content::PROCESS_TYPE_RENDERER; | 227 process.process_type = content::PROCESS_TYPE_RENDERER; |
229 Profile* profile = | 228 Profile* profile = |
230 Profile::FromBrowserContext( | 229 Profile::FromBrowserContext( |
231 render_process_host->GetBrowserContext()); | 230 render_process_host->GetBrowserContext()); |
232 ExtensionService* extension_service = profile->GetExtensionService(); | 231 ExtensionService* extension_service = profile->GetExtensionService(); |
233 extensions::ProcessMap* extension_process_map = NULL; | 232 extensions::ProcessMap* extension_process_map = NULL; |
234 // No extensions on Android. So extension_service can be NULL. | 233 // No extensions on Android. So extension_service can be NULL. |
235 if (extension_service) | 234 if (extension_service) |
236 extension_process_map = extension_service->process_map(); | 235 extension_process_map = extension_service->process_map(); |
237 | 236 |
238 // The RenderProcessHost may host multiple WebContentses. Any | 237 // The RenderProcessHost may host multiple WebContentses. Any |
239 // of them which contain diagnostics information make the whole | 238 // of them which contain diagnostics information make the whole |
240 // process be considered a diagnostics process. | 239 // process be considered a diagnostics process. |
241 content::RenderProcessHost::RenderWidgetHostsIterator iter( | 240 if (!widgets[i]->IsRenderView()) |
242 render_process_host->GetRenderWidgetHostsIterator()); | 241 continue; |
243 for (; !iter.IsAtEnd(); iter.Advance()) { | |
244 const RenderWidgetHost* widget = iter.GetCurrentValue(); | |
245 DCHECK(widget); | |
246 if (!widget || !widget->IsRenderView()) | |
247 continue; | |
248 | 242 |
249 RenderViewHost* host = | 243 RenderViewHost* host = RenderViewHost::From(widgets[i]); |
250 RenderViewHost::From(const_cast<RenderWidgetHost*>(widget)); | 244 WebContents* contents = WebContents::FromRenderViewHost(host); |
251 WebContents* contents = WebContents::FromRenderViewHost(host); | 245 GURL url; |
252 GURL url; | 246 if (contents) { |
253 if (contents) { | 247 url = contents->GetURL(); |
254 url = contents->GetURL(); | 248 SiteData* site_data = |
255 SiteData* site_data = | 249 &chrome_browser->site_data[contents->GetBrowserContext()]; |
256 &chrome_browser->site_data[contents->GetBrowserContext()]; | 250 SiteDetails::CollectSiteInfo(contents, site_data); |
257 SiteDetails::CollectSiteInfo(contents, site_data); | 251 } |
258 } | 252 extensions::ViewType type = extensions::GetViewType(contents); |
259 extensions::ViewType type = extensions::GetViewType(contents); | 253 if (host->GetEnabledBindings() & content::BINDINGS_POLICY_WEB_UI) { |
260 if (host->GetEnabledBindings() & content::BINDINGS_POLICY_WEB_UI) { | 254 process.renderer_type = ProcessMemoryInformation::RENDERER_CHROME; |
261 process.renderer_type = ProcessMemoryInformation::RENDERER_CHROME; | 255 } else if (extension_process_map && |
262 } else if (extension_process_map && | 256 extension_process_map->Contains(host->GetProcess()->GetID())) { |
263 extension_process_map->Contains(host->GetProcess()->GetID())) { | 257 // For our purposes, don't count processes containing only hosted apps |
264 // For our purposes, don't count processes containing only hosted apps | 258 // as extension processes. See also: crbug.com/102533. |
265 // as extension processes. See also: crbug.com/102533. | 259 std::set<std::string> extension_ids = |
266 std::set<std::string> extension_ids = | 260 extension_process_map->GetExtensionsInProcess( |
267 extension_process_map->GetExtensionsInProcess( | 261 host->GetProcess()->GetID()); |
268 host->GetProcess()->GetID()); | 262 for (std::set<std::string>::iterator iter = extension_ids.begin(); |
269 for (std::set<std::string>::iterator iter = extension_ids.begin(); | 263 iter != extension_ids.end(); ++iter) { |
270 iter != extension_ids.end(); ++iter) { | 264 const Extension* extension = |
271 const Extension* extension = | 265 extension_service->GetExtensionById(*iter, false); |
272 extension_service->GetExtensionById(*iter, false); | 266 if (extension && !extension->is_hosted_app()) { |
273 if (extension && !extension->is_hosted_app()) { | 267 process.renderer_type = |
274 process.renderer_type = | 268 ProcessMemoryInformation::RENDERER_EXTENSION; |
275 ProcessMemoryInformation::RENDERER_EXTENSION; | 269 break; |
276 break; | |
277 } | |
278 } | 270 } |
279 } | 271 } |
280 if (extension_process_map && | 272 } |
281 extension_process_map->Contains(host->GetProcess()->GetID())) { | 273 if (extension_process_map && |
282 const Extension* extension = | 274 extension_process_map->Contains(host->GetProcess()->GetID())) { |
283 extension_service->extensions()->GetByID(url.host()); | 275 const Extension* extension = |
284 if (extension) { | 276 extension_service->extensions()->GetByID(url.host()); |
285 string16 title = UTF8ToUTF16(extension->name()); | 277 if (extension) { |
286 process.titles.push_back(title); | 278 string16 title = UTF8ToUTF16(extension->name()); |
287 process.renderer_type = | 279 process.titles.push_back(title); |
288 ProcessMemoryInformation::RENDERER_EXTENSION; | |
289 continue; | |
290 } | |
291 } | |
292 | |
293 if (!contents) { | |
294 process.renderer_type = | 280 process.renderer_type = |
295 ProcessMemoryInformation::RENDERER_INTERSTITIAL; | 281 ProcessMemoryInformation::RENDERER_EXTENSION; |
296 continue; | 282 continue; |
297 } | 283 } |
| 284 } |
298 | 285 |
299 if (type == extensions::VIEW_TYPE_BACKGROUND_CONTENTS) { | 286 if (!contents) { |
300 process.titles.push_back(UTF8ToUTF16(url.spec())); | 287 process.renderer_type = |
301 process.renderer_type = | 288 ProcessMemoryInformation::RENDERER_INTERSTITIAL; |
302 ProcessMemoryInformation::RENDERER_BACKGROUND_APP; | 289 continue; |
303 continue; | 290 } |
304 } | |
305 | 291 |
306 if (type == extensions::VIEW_TYPE_NOTIFICATION) { | 292 if (type == extensions::VIEW_TYPE_BACKGROUND_CONTENTS) { |
307 process.titles.push_back(UTF8ToUTF16(url.spec())); | 293 process.titles.push_back(UTF8ToUTF16(url.spec())); |
308 process.renderer_type = | 294 process.renderer_type = |
309 ProcessMemoryInformation::RENDERER_NOTIFICATION; | 295 ProcessMemoryInformation::RENDERER_BACKGROUND_APP; |
310 continue; | 296 continue; |
311 } | 297 } |
312 | 298 |
313 // Since we have a WebContents and and the renderer type hasn't been | 299 if (type == extensions::VIEW_TYPE_NOTIFICATION) { |
314 // set yet, it must be a normal tabbed renderer. | 300 process.titles.push_back(UTF8ToUTF16(url.spec())); |
315 if (process.renderer_type == ProcessMemoryInformation::RENDERER_UNKNOWN) | 301 process.renderer_type = |
316 process.renderer_type = ProcessMemoryInformation::RENDERER_NORMAL; | 302 ProcessMemoryInformation::RENDERER_NOTIFICATION; |
| 303 continue; |
| 304 } |
317 | 305 |
318 string16 title = contents->GetTitle(); | 306 // Since we have a WebContents and and the renderer type hasn't been |
319 if (!title.length()) | 307 // set yet, it must be a normal tabbed renderer. |
320 title = l10n_util::GetStringUTF16(IDS_DEFAULT_TAB_TITLE); | 308 if (process.renderer_type == ProcessMemoryInformation::RENDERER_UNKNOWN) |
321 process.titles.push_back(title); | 309 process.renderer_type = ProcessMemoryInformation::RENDERER_NORMAL; |
322 | 310 |
323 // We need to check the pending entry as well as the virtual_url to | 311 string16 title = contents->GetTitle(); |
324 // see if it's a chrome://memory URL (we don't want to count these in | 312 if (!title.length()) |
325 // the total memory usage of the browser). | 313 title = l10n_util::GetStringUTF16(IDS_DEFAULT_TAB_TITLE); |
326 // | 314 process.titles.push_back(title); |
327 // When we reach here, chrome://memory will be the pending entry since | 315 |
328 // we haven't responded with any data such that it would be committed. | 316 // We need to check the pending entry as well as the virtual_url to |
329 // If you have another chrome://memory tab open (which would be | 317 // see if it's a chrome://memory URL (we don't want to count these in |
330 // committed), we don't want to count it either, so we also check the | 318 // the total memory usage of the browser). |
331 // last committed entry. | 319 // |
332 // | 320 // When we reach here, chrome://memory will be the pending entry since |
333 // Either the pending or last committed entries can be NULL. | 321 // we haven't responded with any data such that it would be committed. |
334 const NavigationEntry* pending_entry = | 322 // If you have another chrome://memory tab open (which would be |
335 contents->GetController().GetPendingEntry(); | 323 // committed), we don't want to count it either, so we also check the |
336 const NavigationEntry* last_committed_entry = | 324 // last committed entry. |
337 contents->GetController().GetLastCommittedEntry(); | 325 // |
338 if ((last_committed_entry && | 326 // Either the pending or last committed entries can be NULL. |
339 LowerCaseEqualsASCII(last_committed_entry->GetVirtualURL().spec(), | 327 const NavigationEntry* pending_entry = |
340 chrome::kChromeUIMemoryURL)) || | 328 contents->GetController().GetPendingEntry(); |
341 (pending_entry && | 329 const NavigationEntry* last_committed_entry = |
342 LowerCaseEqualsASCII(pending_entry->GetVirtualURL().spec(), | 330 contents->GetController().GetLastCommittedEntry(); |
343 chrome::kChromeUIMemoryURL))) | 331 if ((last_committed_entry && |
344 process.is_diagnostics = true; | 332 LowerCaseEqualsASCII(last_committed_entry->GetVirtualURL().spec(), |
| 333 chrome::kChromeUIMemoryURL)) || |
| 334 (pending_entry && |
| 335 LowerCaseEqualsASCII(pending_entry->GetVirtualURL().spec(), |
| 336 chrome::kChromeUIMemoryURL))) { |
| 337 process.is_diagnostics = true; |
345 } | 338 } |
346 } | 339 } |
347 | 340 |
348 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) | 341 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) |
349 if (process.pid == zygote_pid) { | 342 if (process.pid == zygote_pid) { |
350 process.process_type = content::PROCESS_TYPE_ZYGOTE; | 343 process.process_type = content::PROCESS_TYPE_ZYGOTE; |
351 } else if (process.pid == sandbox_helper_pid) { | 344 } else if (process.pid == sandbox_helper_pid) { |
352 process.process_type = content::PROCESS_TYPE_SANDBOX_HELPER; | 345 process.process_type = content::PROCESS_TYPE_SANDBOX_HELPER; |
353 } | 346 } |
354 #endif | 347 #endif |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
491 int total_sample = static_cast<int>(aggregate_memory / 1000); | 484 int total_sample = static_cast<int>(aggregate_memory / 1000); |
492 UMA_HISTOGRAM_MEMORY_MB("Memory.Total", total_sample); | 485 UMA_HISTOGRAM_MEMORY_MB("Memory.Total", total_sample); |
493 | 486 |
494 // Predict the number of processes needed when isolating all sites and when | 487 // Predict the number of processes needed when isolating all sites and when |
495 // isolating only HTTPS sites. | 488 // isolating only HTTPS sites. |
496 int all_renderer_count = renderer_count + chrome_count + extension_count; | 489 int all_renderer_count = renderer_count + chrome_count + extension_count; |
497 int non_renderer_count = browser.processes.size() - all_renderer_count; | 490 int non_renderer_count = browser.processes.size() - all_renderer_count; |
498 SiteDetails::UpdateHistograms(browser.site_data, all_renderer_count, | 491 SiteDetails::UpdateHistograms(browser.site_data, all_renderer_count, |
499 non_renderer_count); | 492 non_renderer_count); |
500 } | 493 } |
OLD | NEW |