| 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" |
| 11 #include "base/string_util.h" | 11 #include "base/string_util.h" |
| 12 #include "base/stringprintf.h" |
| 12 #include "base/utf_string_conversions.h" | 13 #include "base/utf_string_conversions.h" |
| 13 #include "chrome/browser/extensions/extension_process_manager.h" | 14 #include "chrome/browser/extensions/extension_process_manager.h" |
| 14 #include "chrome/browser/extensions/extension_service.h" | 15 #include "chrome/browser/extensions/extension_service.h" |
| 15 #include "chrome/browser/profiles/profile.h" | 16 #include "chrome/browser/profiles/profile.h" |
| 16 #include "chrome/common/chrome_view_type.h" | 17 #include "chrome/common/chrome_view_type.h" |
| 17 #include "chrome/common/extensions/extension.h" | 18 #include "chrome/common/extensions/extension.h" |
| 18 #include "chrome/common/url_constants.h" | 19 #include "chrome/common/url_constants.h" |
| 19 #include "content/public/browser/browser_child_process_host_iterator.h" | 20 #include "content/public/browser/browser_child_process_host_iterator.h" |
| 20 #include "content/public/browser/browser_thread.h" | 21 #include "content/public/browser/browser_thread.h" |
| 21 #include "content/public/browser/child_process_data.h" | 22 #include "content/public/browser/child_process_data.h" |
| 22 #include "content/public/browser/navigation_controller.h" | 23 #include "content/public/browser/navigation_controller.h" |
| 23 #include "content/public/browser/navigation_entry.h" | 24 #include "content/public/browser/navigation_entry.h" |
| 24 #include "content/public/browser/render_process_host.h" | 25 #include "content/public/browser/render_process_host.h" |
| 25 #include "content/public/browser/render_view_host.h" | 26 #include "content/public/browser/render_view_host.h" |
| 26 #include "content/public/browser/render_view_host_delegate.h" | 27 #include "content/public/browser/render_view_host_delegate.h" |
| 27 #include "content/public/browser/web_contents.h" | 28 #include "content/public/browser/web_contents.h" |
| 28 #include "content/public/common/bindings_policy.h" | 29 #include "content/public/common/bindings_policy.h" |
| 29 #include "content/public/common/process_type.h" | 30 #include "content/public/common/process_type.h" |
| 30 #include "grit/chromium_strings.h" | 31 #include "grit/chromium_strings.h" |
| 31 #include "grit/generated_resources.h" | 32 #include "grit/generated_resources.h" |
| 32 #include "ui/base/l10n/l10n_util.h" | 33 #include "ui/base/l10n/l10n_util.h" |
| 33 | 34 |
| 34 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) | 35 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) |
| 35 #include "content/public/browser/zygote_host_linux.h" | 36 #include "content/public/browser/zygote_host_linux.h" |
| 36 #endif | 37 #endif |
| 37 | 38 |
| 39 using base::StringPrintf; |
| 38 using content::BrowserChildProcessHostIterator; | 40 using content::BrowserChildProcessHostIterator; |
| 39 using content::BrowserThread; | 41 using content::BrowserThread; |
| 40 using content::NavigationEntry; | 42 using content::NavigationEntry; |
| 41 using content::RenderViewHost; | 43 using content::RenderViewHost; |
| 42 using content::RenderWidgetHost; | 44 using content::RenderWidgetHost; |
| 43 using content::WebContents; | 45 using content::WebContents; |
| 44 | 46 |
| 45 // static | 47 // static |
| 46 std::string ProcessMemoryInformation::GetRendererTypeNameInEnglish( | 48 std::string ProcessMemoryInformation::GetRendererTypeNameInEnglish( |
| 47 RendererProcessType type) { | 49 RendererProcessType type) { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 // This operation will hit no fewer than 3 threads. | 110 // This operation will hit no fewer than 3 threads. |
| 109 // | 111 // |
| 110 // The BrowserChildProcessHostIterator can only be accessed from the IO thread. | 112 // The BrowserChildProcessHostIterator can only be accessed from the IO thread. |
| 111 // | 113 // |
| 112 // The RenderProcessHostIterator can only be accessed from the UI thread. | 114 // The RenderProcessHostIterator can only be accessed from the UI thread. |
| 113 // | 115 // |
| 114 // This operation can take 30-100ms to complete. We never want to have | 116 // 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 | 117 // 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. | 118 // expensive parts of this operation over on the file thread. |
| 117 // | 119 // |
| 118 void MemoryDetails::StartFetch() { | 120 void MemoryDetails::StartFetch(UserMetricsMode user_metrics_mode) { |
| 119 // This might get called from the UI or FILE threads, but should not be | 121 // This might get called from the UI or FILE threads, but should not be |
| 120 // getting called from the IO thread. | 122 // getting called from the IO thread. |
| 121 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO)); | 123 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 124 user_metrics_mode_ = user_metrics_mode; |
| 122 | 125 |
| 123 // In order to process this request, we need to use the plugin information. | 126 // 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. | 127 // However, plugin process information is only available from the IO thread. |
| 125 BrowserThread::PostTask( | 128 BrowserThread::PostTask( |
| 126 BrowserThread::IO, FROM_HERE, | 129 BrowserThread::IO, FROM_HERE, |
| 127 base::Bind(&MemoryDetails::CollectChildInfoOnIOThread, this)); | 130 base::Bind(&MemoryDetails::CollectChildInfoOnIOThread, this)); |
| 128 } | 131 } |
| 129 | 132 |
| 130 MemoryDetails::~MemoryDetails() {} | 133 MemoryDetails::~MemoryDetails() {} |
| 131 | 134 |
| 135 std::string MemoryDetails::ToLogString() { |
| 136 std::string log; |
| 137 log.reserve(4096); |
| 138 const ProcessData& chrome = *ChromeBrowser(); |
| 139 for (ProcessMemoryInformationList::const_iterator iter1 = |
| 140 chrome.processes.begin(); |
| 141 iter1 != chrome.processes.end(); ++iter1) { |
| 142 log += ProcessMemoryInformation::GetFullTypeNameInEnglish( |
| 143 iter1->type, iter1->renderer_type); |
| 144 if (!iter1->titles.empty()) { |
| 145 log += " ["; |
| 146 for (std::vector<string16>::const_iterator iter2 = |
| 147 iter1->titles.begin(); |
| 148 iter2 != iter1->titles.end(); ++iter2) { |
| 149 if (iter2 != iter1->titles.begin()) |
| 150 log += "|"; |
| 151 log += UTF16ToUTF8(*iter2); |
| 152 } |
| 153 log += "]"; |
| 154 } |
| 155 log += StringPrintf(" %d MB private, %d MB shared\n", |
| 156 static_cast<int>(iter1->working_set.priv) / 1024, |
| 157 static_cast<int>(iter1->working_set.shared) / 1024); |
| 158 } |
| 159 return log; |
| 160 } |
| 161 |
| 132 void MemoryDetails::CollectChildInfoOnIOThread() { | 162 void MemoryDetails::CollectChildInfoOnIOThread() { |
| 133 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 163 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 134 | 164 |
| 135 std::vector<ProcessMemoryInformation> child_info; | 165 std::vector<ProcessMemoryInformation> child_info; |
| 136 | 166 |
| 137 // Collect the list of child processes. | 167 // Collect the list of child processes. |
| 138 for (BrowserChildProcessHostIterator iter; !iter.Done(); ++iter) { | 168 for (BrowserChildProcessHostIterator iter; !iter.Done(); ++iter) { |
| 139 ProcessMemoryInformation info; | 169 ProcessMemoryInformation info; |
| 140 info.pid = base::GetProcId(iter.GetData().handle); | 170 info.pid = base::GetProcId(iter.GetData().handle); |
| 141 if (!info.pid) | 171 if (!info.pid) |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 for (size_t index = 0; index < chrome_browser->processes.size(); | 345 for (size_t index = 0; index < chrome_browser->processes.size(); |
| 316 index++) { | 346 index++) { |
| 317 if (chrome_browser->processes[index].type == | 347 if (chrome_browser->processes[index].type == |
| 318 content::PROCESS_TYPE_UNKNOWN) { | 348 content::PROCESS_TYPE_UNKNOWN) { |
| 319 chrome_browser->processes.erase( | 349 chrome_browser->processes.erase( |
| 320 chrome_browser->processes.begin() + index); | 350 chrome_browser->processes.begin() + index); |
| 321 index--; | 351 index--; |
| 322 } | 352 } |
| 323 } | 353 } |
| 324 | 354 |
| 325 UpdateHistograms(); | 355 if (user_metrics_mode_ == UPDATE_USER_METRICS) |
| 356 UpdateHistograms(); |
| 326 | 357 |
| 327 OnDetailsAvailable(); | 358 OnDetailsAvailable(); |
| 328 } | 359 } |
| 329 | 360 |
| 330 void MemoryDetails::UpdateHistograms() { | 361 void MemoryDetails::UpdateHistograms() { |
| 331 // Reports a set of memory metrics to UMA. | 362 // Reports a set of memory metrics to UMA. |
| 332 // Memory is measured in KB. | 363 // Memory is measured in KB. |
| 333 | 364 |
| 334 const ProcessData& browser = *ChromeBrowser(); | 365 const ProcessData& browser = *ChromeBrowser(); |
| 335 size_t aggregate_memory = 0; | 366 size_t aggregate_memory = 0; |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 424 UMA_HISTOGRAM_COUNTS_100("Memory.PepperPluginProcessCount", | 455 UMA_HISTOGRAM_COUNTS_100("Memory.PepperPluginProcessCount", |
| 425 pepper_plugin_count); | 456 pepper_plugin_count); |
| 426 UMA_HISTOGRAM_COUNTS_100("Memory.RendererProcessCount", renderer_count); | 457 UMA_HISTOGRAM_COUNTS_100("Memory.RendererProcessCount", renderer_count); |
| 427 UMA_HISTOGRAM_COUNTS_100("Memory.WorkerProcessCount", worker_count); | 458 UMA_HISTOGRAM_COUNTS_100("Memory.WorkerProcessCount", worker_count); |
| 428 // TODO(viettrungluu): Do we want separate counts for the other | 459 // TODO(viettrungluu): Do we want separate counts for the other |
| 429 // (platform-specific) process types? | 460 // (platform-specific) process types? |
| 430 | 461 |
| 431 int total_sample = static_cast<int>(aggregate_memory / 1000); | 462 int total_sample = static_cast<int>(aggregate_memory / 1000); |
| 432 UMA_HISTOGRAM_MEMORY_MB("Memory.Total", total_sample); | 463 UMA_HISTOGRAM_MEMORY_MB("Memory.Total", total_sample); |
| 433 } | 464 } |
| OLD | NEW |