| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 #include <psapi.h> | 6 #include <psapi.h> |
| 7 | 7 |
| 8 #include "base/file_version_info.h" | 8 #include "base/file_version_info.h" |
| 9 #include "base/histogram.h" | 9 #include "base/histogram.h" |
| 10 #include "base/image_util.h" | 10 #include "base/image_util.h" |
| 11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
| 12 #include "base/process_util.h" | 12 #include "base/process_util.h" |
| 13 #include "base/scoped_ptr.h" | 13 #include "base/scoped_ptr.h" |
| 14 #include "base/thread.h" | 14 #include "base/thread.h" |
| 15 #include "chrome/browser/browser_process.h" | 15 #include "chrome/browser/browser_process.h" |
| 16 #include "chrome/browser/chrome_thread.h" | 16 #include "chrome/browser/chrome_thread.h" |
| 17 #include "chrome/browser/plugin_process_host.h" | |
| 18 #include "chrome/browser/plugin_service.h" | |
| 19 #include "chrome/browser/renderer_host/render_process_host.h" | 17 #include "chrome/browser/renderer_host/render_process_host.h" |
| 20 #include "chrome/browser/renderer_host/render_view_host.h" | 18 #include "chrome/browser/renderer_host/render_view_host.h" |
| 21 #include "chrome/browser/tab_contents/tab_contents.h" | 19 #include "chrome/browser/tab_contents/tab_contents.h" |
| 22 #include "chrome/browser/tab_contents/web_contents.h" | 20 #include "chrome/browser/tab_contents/web_contents.h" |
| 21 #include "chrome/common/child_process_info.h" |
| 23 | 22 |
| 24 class RenderViewHostDelegate; | 23 class RenderViewHostDelegate; |
| 25 | 24 |
| 26 // Template of static data we use for finding browser process information. | 25 // Template of static data we use for finding browser process information. |
| 27 // These entries must match the ordering for MemoryDetails::BrowserProcess. | 26 // These entries must match the ordering for MemoryDetails::BrowserProcess. |
| 28 static ProcessData g_process_template[] = { | 27 static ProcessData g_process_template[] = { |
| 29 { L"Chromium", L"chrome.exe", }, | 28 { L"Chromium", L"chrome.exe", }, |
| 30 { L"IE", L"iexplore.exe", }, | 29 { L"IE", L"iexplore.exe", }, |
| 31 { L"Firefox", L"firefox.exe", }, | 30 { L"Firefox", L"firefox.exe", }, |
| 32 { L"Opera", L"opera.exe", }, | 31 { L"Opera", L"opera.exe", }, |
| 33 { L"Safari", L"safari.exe", }, | 32 { L"Safari", L"safari.exe", }, |
| 34 }; | 33 }; |
| 35 | 34 |
| 36 | 35 |
| 37 // About threading: | 36 // About threading: |
| 38 // | 37 // |
| 39 // This operation will hit no fewer than 3 threads. | 38 // This operation will hit no fewer than 3 threads. |
| 40 // | 39 // |
| 41 // The PluginHostIterator can only be accessed from the IO thread. | 40 // The ChildProcessInfo::Iterator can only be accessed from the IO thread. |
| 42 // | 41 // |
| 43 // The RenderProcessHostIterator can only be accessed from the UI thread. | 42 // The RenderProcessHostIterator can only be accessed from the UI thread. |
| 44 // | 43 // |
| 45 // This operation can take 30-100ms to complete. We never want to have | 44 // This operation can take 30-100ms to complete. We never want to have |
| 46 // one task run for that long on the UI or IO threads. So, we run the | 45 // one task run for that long on the UI or IO threads. So, we run the |
| 47 // expensive parts of this operation over on the file thread. | 46 // expensive parts of this operation over on the file thread. |
| 48 // | 47 // |
| 49 | 48 |
| 50 MemoryDetails::MemoryDetails() | 49 MemoryDetails::MemoryDetails() |
| 51 : ui_loop_(NULL) { | 50 : ui_loop_(NULL) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 66 g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE, | 65 g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE, |
| 67 NewRunnableMethod(this, &MemoryDetails::CollectChildInfoOnIOThread)); | 66 NewRunnableMethod(this, &MemoryDetails::CollectChildInfoOnIOThread)); |
| 68 } | 67 } |
| 69 | 68 |
| 70 void MemoryDetails::CollectChildInfoOnIOThread() { | 69 void MemoryDetails::CollectChildInfoOnIOThread() { |
| 71 DCHECK(MessageLoop::current() == | 70 DCHECK(MessageLoop::current() == |
| 72 ChromeThread::GetMessageLoop(ChromeThread::IO)); | 71 ChromeThread::GetMessageLoop(ChromeThread::IO)); |
| 73 | 72 |
| 74 std::vector<ProcessMemoryInformation> child_info; | 73 std::vector<ProcessMemoryInformation> child_info; |
| 75 | 74 |
| 76 // Collect the list of plugins. | 75 // Collect the list of child processes. |
| 77 for (PluginProcessHostIterator plugin_iter; | 76 for (ChildProcessInfo::Iterator iter; !iter.Done(); ++iter) { |
| 78 !plugin_iter.Done(); ++plugin_iter) { | 77 if (!iter->process().handle()) |
| 79 ChildProcessInfo* child = const_cast<PluginProcessHost*>(*plugin_iter); | |
| 80 DCHECK(child); | |
| 81 if (!child || !child->process().handle()) | |
| 82 continue; | 78 continue; |
| 83 | 79 |
| 84 ProcessMemoryInformation info; | 80 ProcessMemoryInformation info; |
| 85 info.pid = child->process().pid(); | 81 info.pid = iter->process().pid(); |
| 86 if (!info.pid) | 82 if (!info.pid) |
| 87 continue; | 83 continue; |
| 88 | 84 |
| 89 info.type = child->type(); | 85 info.type = iter->type(); |
| 90 info.titles.push_back(child->name()); | 86 info.titles.push_back(iter->name()); |
| 91 child_info.push_back(info); | 87 child_info.push_back(info); |
| 92 } | 88 } |
| 93 | 89 |
| 94 // Now go do expensive memory lookups from the file thread. | 90 // Now go do expensive memory lookups from the file thread. |
| 95 ChromeThread::GetMessageLoop(ChromeThread::FILE)->PostTask(FROM_HERE, | 91 ChromeThread::GetMessageLoop(ChromeThread::FILE)->PostTask(FROM_HERE, |
| 96 NewRunnableMethod(this, &MemoryDetails::CollectProcessData, child_info)); | 92 NewRunnableMethod(this, &MemoryDetails::CollectProcessData, child_info)); |
| 97 } | 93 } |
| 98 | 94 |
| 99 void MemoryDetails::CollectProcessData( | 95 void MemoryDetails::CollectProcessData( |
| 100 std::vector<ProcessMemoryInformation> child_info) { | 96 std::vector<ProcessMemoryInformation> child_info) { |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 237 } | 233 } |
| 238 } | 234 } |
| 239 | 235 |
| 240 // Get rid of other Chrome processes that are from a different profile. | 236 // Get rid of other Chrome processes that are from a different profile. |
| 241 for (size_t index = 0; index < process_data_[CHROME_BROWSER].processes.size(); | 237 for (size_t index = 0; index < process_data_[CHROME_BROWSER].processes.size(); |
| 242 index++) { | 238 index++) { |
| 243 if (process_data_[CHROME_BROWSER].processes[index].type == | 239 if (process_data_[CHROME_BROWSER].processes[index].type == |
| 244 ChildProcessInfo::UNKNOWN_PROCESS) { | 240 ChildProcessInfo::UNKNOWN_PROCESS) { |
| 245 process_data_[CHROME_BROWSER].processes.erase( | 241 process_data_[CHROME_BROWSER].processes.erase( |
| 246 process_data_[CHROME_BROWSER].processes.begin() + index); | 242 process_data_[CHROME_BROWSER].processes.begin() + index); |
| 247 index --; | 243 index--; |
| 248 } | 244 } |
| 249 } | 245 } |
| 250 | 246 |
| 251 UpdateHistograms(); | 247 UpdateHistograms(); |
| 252 | 248 |
| 253 OnDetailsAvailable(); | 249 OnDetailsAvailable(); |
| 254 } | 250 } |
| 255 | 251 |
| 256 void MemoryDetails::UpdateHistograms() { | 252 void MemoryDetails::UpdateHistograms() { |
| 257 // Reports a set of memory metrics to UMA. | 253 // Reports a set of memory metrics to UMA. |
| (...skipping 25 matching lines...) Expand all Loading... |
| 283 } | 279 } |
| 284 | 280 |
| 285 UMA_HISTOGRAM_COUNTS_100(L"Memory.ProcessCount", | 281 UMA_HISTOGRAM_COUNTS_100(L"Memory.ProcessCount", |
| 286 static_cast<int>(browser.processes.size())); | 282 static_cast<int>(browser.processes.size())); |
| 287 UMA_HISTOGRAM_COUNTS_100(L"Memory.PluginProcessCount", plugin_count); | 283 UMA_HISTOGRAM_COUNTS_100(L"Memory.PluginProcessCount", plugin_count); |
| 288 UMA_HISTOGRAM_COUNTS_100(L"Memory.WorkerProcessCount", worker_count); | 284 UMA_HISTOGRAM_COUNTS_100(L"Memory.WorkerProcessCount", worker_count); |
| 289 | 285 |
| 290 int total_sample = static_cast<int>(aggregate_memory / 1000); | 286 int total_sample = static_cast<int>(aggregate_memory / 1000); |
| 291 UMA_HISTOGRAM_MEMORY_MB(L"Memory.Total", total_sample); | 287 UMA_HISTOGRAM_MEMORY_MB(L"Memory.Total", total_sample); |
| 292 } | 288 } |
| OLD | NEW |