diff options
author | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-01 00:12:58 +0000 |
---|---|---|
committer | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-01 00:12:58 +0000 |
commit | 54fd1d3ac91d117719f157fad3ead41518865f52 (patch) | |
tree | be3ec12e4da55384888a13707d8eee0f05e60a07 /chrome/browser/memory_details.cc | |
parent | 1f758608ae7c38a580d574ec7e5061eb0bfa7ee2 (diff) | |
download | chromium_src-54fd1d3ac91d117719f157fad3ead41518865f52.zip chromium_src-54fd1d3ac91d117719f157fad3ead41518865f52.tar.gz chromium_src-54fd1d3ac91d117719f157fad3ead41518865f52.tar.bz2 |
Linux: about:memory
(based on http://code.google.com/p/chromium/issues/detail?id=16251)
Add about:memory support to Linux. Rather than try and copy the
Windows output, we use a couple of metrics which make more sense on
Linux: USS and PSS.
http://codereview.chromium.org/177024
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@24979 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/memory_details.cc')
-rw-r--r-- | chrome/browser/memory_details.cc | 163 |
1 files changed, 35 insertions, 128 deletions
diff --git a/chrome/browser/memory_details.cc b/chrome/browser/memory_details.cc index cfdafc3..219333f 100644 --- a/chrome/browser/memory_details.cc +++ b/chrome/browser/memory_details.cc @@ -3,7 +3,6 @@ // found in the LICENSE file. #include "chrome/browser/memory_details.h" -#include <psapi.h> #include "app/l10n_util.h" #include "base/file_version_info.h" @@ -19,11 +18,10 @@ #include "chrome/common/url_constants.h" #include "grit/chromium_strings.h" -class RenderViewHostDelegate; - -// Template of static data we use for finding browser process information. -// These entries must match the ordering for MemoryDetails::BrowserProcess. -static ProcessData g_process_template[MemoryDetails::MAX_BROWSERS]; +#if defined(OS_LINUX) +#include "chrome/browser/zygote_host_linux.h" +#include "chrome/browser/renderer_host/render_sandbox_host_linux.h" +#endif // About threading: // @@ -38,25 +36,6 @@ static ProcessData g_process_template[MemoryDetails::MAX_BROWSERS]; // expensive parts of this operation over on the file thread. // -MemoryDetails::MemoryDetails() : ui_loop_(NULL) { - static const std::wstring google_browser_name = - l10n_util::GetString(IDS_PRODUCT_NAME); - ProcessData g_process_template[MemoryDetails::MAX_BROWSERS] = { - { google_browser_name.c_str(), L"chrome.exe", }, - { L"IE", L"iexplore.exe", }, - { L"Firefox", L"firefox.exe", }, - { L"Opera", L"opera.exe", }, - { L"Safari", L"safari.exe", }, - { L"IE (64bit)", L"iexplore.exe", }, - { L"Konqueror", L"konqueror.exe", }, - }; - - for (int index = 0; index < arraysize(g_process_template); ++index) { - process_data_[index].name = g_process_template[index].name; - process_data_[index].process_name = g_process_template[index].process_name; - } -} - void MemoryDetails::StartFetch() { ui_loop_ = MessageLoop::current(); @@ -92,106 +71,17 @@ void MemoryDetails::CollectChildInfoOnIOThread() { NewRunnableMethod(this, &MemoryDetails::CollectProcessData, child_info)); } -void MemoryDetails::CollectProcessData( - std::vector<ProcessMemoryInformation> child_info) { - DCHECK(MessageLoop::current() == - ChromeThread::GetMessageLoop(ChromeThread::FILE)); - - // Clear old data. - for (int index = 0; index < arraysize(g_process_template); index++) - process_data_[index].processes.clear(); - - SYSTEM_INFO system_info; - GetNativeSystemInfo(&system_info); - bool is_64bit_os = - system_info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64; - - ScopedHandle snapshot(::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)); - PROCESSENTRY32 process_entry = {sizeof(PROCESSENTRY32)}; - if (!snapshot.Get()) { - LOG(ERROR) << "CreateToolhelp32Snaphot failed: " << GetLastError(); - return; - } - if (!::Process32First(snapshot, &process_entry)) { - LOG(ERROR) << "Process32First failed: " << GetLastError(); - return; - } - do { - int pid = process_entry.th32ProcessID; - ScopedHandle handle(::OpenProcess( - PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid)); - if (!handle.Get()) - continue; - bool is_64bit_process = false; - // IsWow64Process() returns FALSE for a 32bit process on a 32bit OS. - // We need to check if the real OS is 64bit. - if (is_64bit_os) { - BOOL is_wow64 = FALSE; - // IsWow64Process() is supported by Windows XP SP2 or later. - IsWow64Process(handle, &is_wow64); - is_64bit_process = !is_wow64; - } - for (int index2 = 0; index2 < arraysize(g_process_template); index2++) { - if (_wcsicmp(process_data_[index2].process_name, - process_entry.szExeFile) != 0) - continue; - if (index2 == IE_BROWSER && is_64bit_process) - continue; // Should use IE_64BIT_BROWSER - // Get Memory Information. - ProcessMemoryInformation info; - info.pid = pid; - if (info.pid == GetCurrentProcessId()) - info.type = ChildProcessInfo::BROWSER_PROCESS; - else - info.type = ChildProcessInfo::UNKNOWN_PROCESS; - - scoped_ptr<base::ProcessMetrics> metrics; - metrics.reset(base::ProcessMetrics::CreateProcessMetrics(handle)); - metrics->GetCommittedKBytes(&info.committed); - metrics->GetWorkingSetKBytes(&info.working_set); - - // Get Version Information. - TCHAR name[MAX_PATH]; - if (index2 == CHROME_BROWSER) { - scoped_ptr<FileVersionInfo> version_info( - FileVersionInfo::CreateFileVersionInfoForCurrentModule()); - if (version_info != NULL) - info.version = version_info->file_version(); - // Check if this is one of the child processes whose data we collected - // on the IO thread, and if so copy over that data. - for (size_t child = 0; child < child_info.size(); child++) { - if (child_info[child].pid != info.pid) - continue; - info.titles = child_info[child].titles; - info.type = child_info[child].type; - break; - } - } else if (GetModuleFileNameEx(handle, NULL, name, MAX_PATH - 1)) { - std::wstring str_name(name); - scoped_ptr<FileVersionInfo> version_info( - FileVersionInfo::CreateFileVersionInfo(str_name)); - if (version_info != NULL) { - info.version = version_info->product_version(); - info.product_name = version_info->product_name(); - } - } - - // Add the process info to our list. - process_data_[index2].processes.push_back(info); - break; - } - } while (::Process32Next(snapshot, &process_entry)); - - // Finally return to the browser thread. - ui_loop_->PostTask(FROM_HERE, - NewRunnableMethod(this, &MemoryDetails::CollectChildInfoOnUIThread)); -} - void MemoryDetails::CollectChildInfoOnUIThread() { DCHECK(MessageLoop::current() == ui_loop_); +#if defined(OS_LINUX) + const pid_t zygote_pid = Singleton<ZygoteHost>()->pid(); + const pid_t sandbox_helper_pid = Singleton<RenderSandboxHostLinux>()->pid(); +#endif + + ProcessData* const chrome_browser = ChromeBrowser(); // Get more information about the process. - for (size_t index = 0; index < process_data_[CHROME_BROWSER].processes.size(); + for (size_t index = 0; index < chrome_browser->processes.size(); index++) { // Check if it's a renderer, if so get the list of page titles in it and // check if it's a diagnostics-related process. We skip all diagnostics @@ -199,10 +89,11 @@ void MemoryDetails::CollectChildInfoOnUIThread() { // the tab contents. RenderProcessHost::iterator renderer_iter( RenderProcessHost::AllHostsIterator()); + ProcessMemoryInformation& process = + chrome_browser->processes[index]; + for (; !renderer_iter.IsAtEnd(); renderer_iter.Advance()) { DCHECK(renderer_iter.GetCurrentValue()); - ProcessMemoryInformation& process = - process_data_[CHROME_BROWSER].processes[index]; if (process.pid != renderer_iter.GetCurrentValue()->process().pid()) continue; process.type = ChildProcessInfo::RENDER_PROCESS; @@ -257,15 +148,23 @@ void MemoryDetails::CollectChildInfoOnUIThread() { process.is_diagnostics = true; } } + +#if defined(OS_LINUX) + if (process.pid == zygote_pid) { + process.type = ChildProcessInfo::ZYGOTE_PROCESS; + } else if (process.pid == sandbox_helper_pid) { + process.type = ChildProcessInfo::SANDBOX_HELPER_PROCESS; + } +#endif } // Get rid of other Chrome processes that are from a different profile. - for (size_t index = 0; index < process_data_[CHROME_BROWSER].processes.size(); + for (size_t index = 0; index < chrome_browser->processes.size(); index++) { - if (process_data_[CHROME_BROWSER].processes[index].type == + if (chrome_browser->processes[index].type == ChildProcessInfo::UNKNOWN_PROCESS) { - process_data_[CHROME_BROWSER].processes.erase( - process_data_[CHROME_BROWSER].processes.begin() + index); + chrome_browser->processes.erase( + chrome_browser->processes.begin() + index); index--; } } @@ -279,7 +178,7 @@ void MemoryDetails::UpdateHistograms() { // Reports a set of memory metrics to UMA. // Memory is measured in KB. - ProcessData browser = process_data_[CHROME_BROWSER]; + const ProcessData& browser = *ChromeBrowser(); size_t aggregate_memory = 0; int plugin_count = 0; int worker_count = 0; @@ -301,6 +200,14 @@ void MemoryDetails::UpdateHistograms() { UMA_HISTOGRAM_MEMORY_KB("Memory.Worker", sample); worker_count++; break; + case ChildProcessInfo::ZYGOTE_PROCESS: + UMA_HISTOGRAM_MEMORY_KB("Memory.Zygote", sample); + break; + case ChildProcessInfo::SANDBOX_HELPER_PROCESS: + UMA_HISTOGRAM_MEMORY_KB("Memory.SandboxHelper", sample); + break; + default: + NOTREACHED(); } } UMA_HISTOGRAM_MEMORY_KB("Memory.BackingStore", |