Chromium Code Reviews| Index: chrome/browser/memory_details.cc |
| diff --git a/chrome/browser/memory_details.cc b/chrome/browser/memory_details.cc |
| index d9e95823f99a9a595afd322916c66e4178ae01c7..d9a742e099e10e3c19d5276bd2cec0674c053852 100644 |
| --- a/chrome/browser/memory_details.cc |
| +++ b/chrome/browser/memory_details.cc |
| @@ -39,8 +39,10 @@ using base::StringPrintf; |
| using content::BrowserChildProcessHostIterator; |
| using content::BrowserThread; |
| using content::NavigationEntry; |
| +using content::RenderProcessHost; |
| using content::RenderViewHost; |
| using content::RenderWidgetHost; |
| +using content::SiteInstance; |
| using content::WebContents; |
| using extensions::Extension; |
| @@ -93,6 +95,10 @@ bool ProcessMemoryInformation::operator<( |
| return working_set.priv < rhs.working_set.priv; |
| } |
| +SiteData::SiteData() {} |
| + |
| +SiteData::~SiteData() {} |
| + |
| ProcessData::ProcessData() {} |
| ProcessData::ProcessData(const ProcessData& rhs) |
| @@ -250,8 +256,10 @@ void MemoryDetails::CollectChildInfoOnUIThread() { |
| RenderViewHost::From(const_cast<RenderWidgetHost*>(widget)); |
| WebContents* contents = WebContents::FromRenderViewHost(host); |
| GURL url; |
| - if (contents) |
| + if (contents) { |
| url = contents->GetURL(); |
| + CollectSiteInfo(contents); |
| + } |
| extensions::ViewType type = extensions::GetViewType(contents); |
| if (host->GetEnabledBindings() & content::BINDINGS_POLICY_WEB_UI) { |
| process.renderer_type = ProcessMemoryInformation::RENDERER_CHROME; |
| @@ -367,6 +375,57 @@ void MemoryDetails::CollectChildInfoOnUIThread() { |
| OnDetailsAvailable(); |
| } |
| +void MemoryDetails::CollectSiteInfo(WebContents* contents) { |
| + ProcessData* const chrome_browser = ChromeBrowser(); |
| + |
| + // Keep track of data for each BrowserContext separately, since tabs in |
| + // different BrowserContexts can't share processes. |
| + content::BrowserContext* browser_context = contents->GetBrowserContext(); |
| + SiteData* site_data = &chrome_browser->site_data[browser_context]; |
| + |
| + // Find the BrowsingInstance this WebContents belongs to by iterating over |
| + // the "primary" SiteInstances of each BrowsingInstance we've seen so far. |
| + SiteInstance* instance = contents->GetSiteInstance(); |
| + SiteInstance* primary = NULL; |
| + for (size_t i = 0; i < site_data->instances.size(); ++i) { |
| + if (instance->IsRelatedSiteInstance(site_data->instances[i])) { |
| + primary = site_data->instances[i]; |
| + break; |
| + } |
| + } |
| + if (!primary) { |
| + // Remember this as the "primary" SiteInstance of a new BrowsingInstance. |
| + primary = instance; |
| + site_data->instances.push_back(instance); |
| + } |
| + |
| + // Now keep track of how many sites we have in this BrowsingInstance (and |
| + // overall), including sites in iframes. |
| + std::set<GURL> sites_in_tab = contents->GetSitesInTab(); |
| + for (std::set<GURL>::iterator iter = sites_in_tab.begin(); |
| + iter != sites_in_tab.end(); ++iter) { |
|
nasko
2013/06/11 20:16:37
nit: Shouldn't the increment part of the loop be o
Charlie Reis
2013/06/11 21:36:39
No, this looks like a common pattern. You only ne
|
| + // Skip about:blank, since we won't usually give it its own process. |
| + if (iter->is_empty()) |
|
nasko
2013/06/11 20:16:37
Is "about:blank" an actual empty GURL? I thought w
Charlie Reis
2013/06/11 21:36:39
It comes from GetSiteForURL, which has the comment
|
| + continue; |
| + |
| + // Make sure we don't overcount process-per-site sites, like the NTP. |
| + if (RenderProcessHost::ShouldUseProcessPerSite(browser_context, *iter) && |
| + site_data->sites.find(*iter) != site_data->sites.end()) { |
| + continue; |
| + } |
| + |
| + site_data->sites.insert(*iter); |
| + site_data->instance_site_map[primary->GetId()].insert(*iter); |
| + |
| + // Also keep track of how things would look if we only isolated HTTPS sites. |
| + // In this model, all HTTP sites are grouped into one "http://" site. HTTPS |
| + // and other schemes (e.g., chrome:) are still isolated. |
| + GURL https_site = iter->SchemeIs("http") ? GURL("http://") : *iter; |
| + site_data->https_sites.insert(https_site); |
| + site_data->instance_https_site_map[primary->GetId()].insert(https_site); |
| + } |
| +} |
| + |
| void MemoryDetails::UpdateHistograms() { |
| // Reports a set of memory metrics to UMA. |
| // Memory is measured in KB. |
| @@ -381,6 +440,7 @@ void MemoryDetails::UpdateHistograms() { |
| int renderer_count = 0; |
| int other_count = 0; |
| int worker_count = 0; |
| + int process_limit = RenderProcessHost::GetMaxRendererProcessCount(); |
| for (size_t index = 0; index < browser.processes.size(); index++) { |
| int sample = static_cast<int>(browser.processes[index].working_set.priv); |
| aggregate_memory += sample; |
| @@ -467,6 +527,7 @@ void MemoryDetails::UpdateHistograms() { |
| UMA_HISTOGRAM_MEMORY_MB("Memory.Graphics", meminfo.gem_size / 1024 / 1024); |
| #endif |
| + UMA_HISTOGRAM_COUNTS_100("Memory.ProcessLimit", process_limit); |
| UMA_HISTOGRAM_COUNTS_100("Memory.ProcessCount", |
| static_cast<int>(browser.processes.size())); |
| UMA_HISTOGRAM_COUNTS_100("Memory.ChromeProcessCount", chrome_count); |
| @@ -484,4 +545,74 @@ void MemoryDetails::UpdateHistograms() { |
| int total_sample = static_cast<int>(aggregate_memory / 1000); |
| UMA_HISTOGRAM_MEMORY_MB("Memory.Total", total_sample); |
| + |
| + // Sum the number of sites and SiteInstances in each BrowserContext. |
| + int num_sites = 0; |
| + int num_https_sites = 0; |
| + int num_browsing_instances = 0; |
| + int num_isolated_site_instances = 0; |
| + int num_isolated_https_site_instances = 0; |
| + for (BrowserContextSiteDataMap::const_iterator i = browser.site_data.begin(); |
| + i != browser.site_data.end(); ++i) { |
| + num_sites += i->second.sites.size(); |
| + num_https_sites += i->second.https_sites.size(); |
| + num_browsing_instances += i->second.instance_site_map.size(); |
| + for (BrowsingInstanceSiteMap::const_iterator iter = |
| + i->second.instance_site_map.begin(); |
| + iter != i->second.instance_site_map.end(); ++iter) { |
| + num_isolated_site_instances += iter->second.size(); |
| + } |
| + for (BrowsingInstanceSiteMap::const_iterator iter = |
| + i->second.instance_https_site_map.begin(); |
| + iter != i->second.instance_https_site_map.end(); ++iter) { |
| + num_isolated_https_site_instances += iter->second.size(); |
| + } |
| + } |
| + |
| + // Predict the number of processes needed when isolating all sites and when |
| + // isolating only HTTPS sites. |
| + int process_count_lower_bound = num_sites; |
| + int process_count_upper_bound = num_sites + process_limit - 1; |
| + int process_count_estimate = std::min( |
| + num_isolated_site_instances, process_count_upper_bound); |
| + |
| + int process_count_https_lower_bound = num_https_sites; |
| + int process_count_https_upper_bound = num_https_sites + process_limit - 1; |
| + int process_count_https_estimate = std::min( |
| + num_isolated_https_site_instances, process_count_https_upper_bound); |
| + |
| + // Just renderer process count: |
| + int all_renderer_count = renderer_count + chrome_count + extension_count; |
| + UMA_HISTOGRAM_COUNTS_100("SiteIsolation.CurrentRendererProcessCount", |
| + all_renderer_count); |
| + UMA_HISTOGRAM_COUNTS_100( |
| + "SiteIsolation.BrowsingInstanceCount", |
| + num_browsing_instances); |
| + UMA_HISTOGRAM_COUNTS_100( |
| + "SiteIsolation.IsolateAllSitesProcessCountNoLimit", |
| + num_isolated_site_instances); |
| + UMA_HISTOGRAM_COUNTS_100( |
| + "SiteIsolation.IsolateAllSitesProcessCountLowerBound", |
| + process_count_lower_bound); |
| + UMA_HISTOGRAM_COUNTS_100( |
| + "SiteIsolation.IsolateAllSitesProcessCountEstimate", |
| + process_count_estimate); |
| + UMA_HISTOGRAM_COUNTS_100( |
| + "SiteIsolation.IsolateHttpsSitesProcessCountNoLimit", |
| + num_isolated_https_site_instances); |
| + UMA_HISTOGRAM_COUNTS_100( |
| + "SiteIsolation.IsolateHttpsSitesProcessCountLowerBound", |
| + process_count_https_lower_bound); |
| + UMA_HISTOGRAM_COUNTS_100( |
| + "SiteIsolation.IsolateHttpsSitesProcessCountEstimate", |
| + process_count_https_estimate); |
| + |
| + // Total process count: |
| + int non_renderer_count = browser.processes.size() - all_renderer_count; |
| + UMA_HISTOGRAM_COUNTS_100( |
| + "SiteIsolation.IsolateAllSitesTotalProcessCountEstimate", |
| + process_count_estimate + non_renderer_count); |
| + UMA_HISTOGRAM_COUNTS_100( |
| + "SiteIsolation.IsolateHttpsSitesTotalProcessCountEstimate", |
| + process_count_https_estimate + non_renderer_count); |
| } |