Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(38)

Side by Side Diff: chrome/browser/memory_details.cc

Issue 100111: Support for showing memory usage of 64-bit IE in a 32-bit Chromium ... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/memory_details.h ('k') | chrome/browser/resources/about_memory.html » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/string_util.h" 9 #include "base/string_util.h"
10 #include "chrome/browser/browser_process.h" 10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/chrome_thread.h" 11 #include "chrome/browser/chrome_thread.h"
12 #include "chrome/browser/renderer_host/render_process_host.h" 12 #include "chrome/browser/renderer_host/render_process_host.h"
13 #include "chrome/browser/tab_contents/navigation_entry.h" 13 #include "chrome/browser/tab_contents/navigation_entry.h"
14 #include "chrome/browser/tab_contents/web_contents.h" 14 #include "chrome/browser/tab_contents/web_contents.h"
15 #include "chrome/common/child_process_host.h" 15 #include "chrome/common/child_process_host.h"
16 #include "chrome/common/url_constants.h" 16 #include "chrome/common/url_constants.h"
17 17
18 class RenderViewHostDelegate; 18 class RenderViewHostDelegate;
19 19
20 // Template of static data we use for finding browser process information. 20 // Template of static data we use for finding browser process information.
21 // These entries must match the ordering for MemoryDetails::BrowserProcess. 21 // These entries must match the ordering for MemoryDetails::BrowserProcess.
22 static ProcessData g_process_template[] = { 22 static ProcessData
23 g_process_template[MemoryDetails::MAX_BROWSERS] = {
23 { L"Chromium", L"chrome.exe", }, 24 { L"Chromium", L"chrome.exe", },
24 { L"IE", L"iexplore.exe", }, 25 { L"IE", L"iexplore.exe", },
25 { L"Firefox", L"firefox.exe", }, 26 { L"Firefox", L"firefox.exe", },
26 { L"Opera", L"opera.exe", }, 27 { L"Opera", L"opera.exe", },
27 { L"Safari", L"safari.exe", }, 28 { L"Safari", L"safari.exe", },
29 { L"IE (64bit)", L"iexplore.exe", },
28 }; 30 };
29 31
30 32
31 // About threading: 33 // About threading:
32 // 34 //
33 // This operation will hit no fewer than 3 threads. 35 // This operation will hit no fewer than 3 threads.
34 // 36 //
35 // The ChildProcessInfo::Iterator can only be accessed from the IO thread. 37 // The ChildProcessInfo::Iterator can only be accessed from the IO thread.
36 // 38 //
37 // The RenderProcessHostIterator can only be accessed from the UI thread. 39 // The RenderProcessHostIterator can only be accessed from the UI thread.
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 // Now go do expensive memory lookups from the file thread. 84 // Now go do expensive memory lookups from the file thread.
83 ChromeThread::GetMessageLoop(ChromeThread::FILE)->PostTask(FROM_HERE, 85 ChromeThread::GetMessageLoop(ChromeThread::FILE)->PostTask(FROM_HERE,
84 NewRunnableMethod(this, &MemoryDetails::CollectProcessData, child_info)); 86 NewRunnableMethod(this, &MemoryDetails::CollectProcessData, child_info));
85 } 87 }
86 88
87 void MemoryDetails::CollectProcessData( 89 void MemoryDetails::CollectProcessData(
88 std::vector<ProcessMemoryInformation> child_info) { 90 std::vector<ProcessMemoryInformation> child_info) {
89 DCHECK(MessageLoop::current() == 91 DCHECK(MessageLoop::current() ==
90 ChromeThread::GetMessageLoop(ChromeThread::FILE)); 92 ChromeThread::GetMessageLoop(ChromeThread::FILE));
91 93
92 int array_size = 32;
93 scoped_ptr_malloc<DWORD> process_list;
94 DWORD bytes_used = 0;
95 do {
96 array_size *= 2;
97 process_list.reset(static_cast<DWORD*>(
98 realloc(process_list.release(), sizeof(DWORD) * array_size)));
99 // EnumProcesses doesn't return an error if the array is too small.
100 // We have to check if the return buffer is full, and if so, call it
101 // again. See msdn docs for more info.
102 if (!EnumProcesses(process_list.get(), array_size * sizeof(DWORD),
103 &bytes_used)) {
104 LOG(ERROR) << "EnumProcesses failed: " << GetLastError();
105 return;
106 }
107 } while (bytes_used == (array_size * sizeof(DWORD)));
108
109 int num_processes = bytes_used / sizeof(DWORD);
110
111 // Clear old data. 94 // Clear old data.
112 for (int index = 0; index < arraysize(g_process_template); index++) 95 for (int index = 0; index < arraysize(g_process_template); index++)
113 process_data_[index].processes.clear(); 96 process_data_[index].processes.clear();
114 97
115 for (int index = 0; index < num_processes; index++) { 98 SYSTEM_INFO system_info;
116 int pid = process_list.get()[index]; 99 GetNativeSystemInfo(&system_info);
117 ScopedHandle handle(OpenProcess( 100 bool is_64bit_os =
101 system_info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64;
102
103 ScopedHandle snapshot(::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0));
104 PROCESSENTRY32 process_entry = {sizeof(PROCESSENTRY32)};
105 if (!snapshot.Get()) {
106 LOG(ERROR) << "CreateToolhelp32Snaphot failed: " << GetLastError();
107 return;
108 }
109 if (!::Process32First(snapshot, &process_entry)) {
110 LOG(ERROR) << "Process32First failed: " << GetLastError();
111 return;
112 }
113 do {
114 int pid = process_entry.th32ProcessID;
115 ScopedHandle handle(::OpenProcess(
118 PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid)); 116 PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid));
119 if (!handle.Get()) 117 if (!handle.Get())
120 continue; 118 continue;
121 TCHAR name[MAX_PATH]; 119 bool is_64bit_process = false;
122 if (!GetModuleBaseName(handle, NULL, name, MAX_PATH - 1)) 120 // IsWow64Process() returns FALSE for a 32bit process on a 32bit OS.
123 continue; 121 // We need to check if the real OS is 64bit.
122 if (is_64bit_os) {
123 BOOL is_wow64 = FALSE;
124 // IsWow64Process() is supported by Windows XP SP2 or later.
125 IsWow64Process(handle, &is_wow64);
126 is_64bit_process = !is_wow64;
127 }
124 for (int index2 = 0; index2 < arraysize(g_process_template); index2++) { 128 for (int index2 = 0; index2 < arraysize(g_process_template); index2++) {
125 if (_wcsicmp(process_data_[index2].process_name, name) != 0) 129 if (_wcsicmp(process_data_[index2].process_name,
130 process_entry.szExeFile) != 0)
126 continue; 131 continue;
132 if (index2 == IE_BROWSER && is_64bit_process)
133 continue; // Should use IE_64BIT_BROWSER
127 // Get Memory Information. 134 // Get Memory Information.
128 ProcessMemoryInformation info; 135 ProcessMemoryInformation info;
129 info.pid = pid; 136 info.pid = pid;
130 if (info.pid == GetCurrentProcessId()) 137 if (info.pid == GetCurrentProcessId())
131 info.type = ChildProcessInfo::BROWSER_PROCESS; 138 info.type = ChildProcessInfo::BROWSER_PROCESS;
132 else 139 else
133 info.type = ChildProcessInfo::UNKNOWN_PROCESS; 140 info.type = ChildProcessInfo::UNKNOWN_PROCESS;
134 141
135 scoped_ptr<base::ProcessMetrics> metrics; 142 scoped_ptr<base::ProcessMetrics> metrics;
136 metrics.reset(base::ProcessMetrics::CreateProcessMetrics(handle)); 143 metrics.reset(base::ProcessMetrics::CreateProcessMetrics(handle));
137 metrics->GetCommittedKBytes(&info.committed); 144 metrics->GetCommittedKBytes(&info.committed);
138 metrics->GetWorkingSetKBytes(&info.working_set); 145 metrics->GetWorkingSetKBytes(&info.working_set);
139 146
140 // Get Version Information. 147 // Get Version Information.
141 if (index2 == 0) { // Chrome 148 TCHAR name[MAX_PATH];
149 if (index2 == CHROME_BROWSER) {
142 scoped_ptr<FileVersionInfo> version_info( 150 scoped_ptr<FileVersionInfo> version_info(
143 FileVersionInfo::CreateFileVersionInfoForCurrentModule()); 151 FileVersionInfo::CreateFileVersionInfoForCurrentModule());
144 if (version_info != NULL) 152 if (version_info != NULL)
145 info.version = version_info->file_version(); 153 info.version = version_info->file_version();
146 // Check if this is one of the child processes whose data we collected 154 // Check if this is one of the child processes whose data we collected
147 // on the IO thread, and if so copy over that data. 155 // on the IO thread, and if so copy over that data.
148 for (size_t child = 0; child < child_info.size(); child++) { 156 for (size_t child = 0; child < child_info.size(); child++) {
149 if (child_info[child].pid != info.pid) 157 if (child_info[child].pid != info.pid)
150 continue; 158 continue;
151 info.titles = child_info[child].titles; 159 info.titles = child_info[child].titles;
152 info.type = child_info[child].type; 160 info.type = child_info[child].type;
153 break; 161 break;
154 } 162 }
155 } else if (GetModuleFileNameEx(handle, NULL, name, MAX_PATH - 1)) { 163 } else if (GetModuleFileNameEx(handle, NULL, name, MAX_PATH - 1)) {
156 std::wstring str_name(name); 164 std::wstring str_name(name);
157 scoped_ptr<FileVersionInfo> version_info( 165 scoped_ptr<FileVersionInfo> version_info(
158 FileVersionInfo::CreateFileVersionInfo(str_name)); 166 FileVersionInfo::CreateFileVersionInfo(str_name));
159 if (version_info != NULL) { 167 if (version_info != NULL) {
160 info.version = version_info->product_version(); 168 info.version = version_info->product_version();
161 info.product_name = version_info->product_name(); 169 info.product_name = version_info->product_name();
162 } 170 }
163 } 171 }
164 172
165 // Add the process info to our list. 173 // Add the process info to our list.
166 process_data_[index2].processes.push_back(info); 174 process_data_[index2].processes.push_back(info);
167 break; 175 break;
168 } 176 }
169 } 177 } while (::Process32Next(snapshot, &process_entry));
170 178
171 // Finally return to the browser thread. 179 // Finally return to the browser thread.
172 ui_loop_->PostTask(FROM_HERE, 180 ui_loop_->PostTask(FROM_HERE,
173 NewRunnableMethod(this, &MemoryDetails::CollectChildInfoOnUIThread)); 181 NewRunnableMethod(this, &MemoryDetails::CollectChildInfoOnUIThread));
174 } 182 }
175 183
176 void MemoryDetails::CollectChildInfoOnUIThread() { 184 void MemoryDetails::CollectChildInfoOnUIThread() {
177 DCHECK(MessageLoop::current() == ui_loop_); 185 DCHECK(MessageLoop::current() == ui_loop_);
178 186
179 // Get more information about the process. 187 // Get more information about the process.
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 } 299 }
292 300
293 UMA_HISTOGRAM_COUNTS_100("Memory.ProcessCount", 301 UMA_HISTOGRAM_COUNTS_100("Memory.ProcessCount",
294 static_cast<int>(browser.processes.size())); 302 static_cast<int>(browser.processes.size()));
295 UMA_HISTOGRAM_COUNTS_100("Memory.PluginProcessCount", plugin_count); 303 UMA_HISTOGRAM_COUNTS_100("Memory.PluginProcessCount", plugin_count);
296 UMA_HISTOGRAM_COUNTS_100("Memory.WorkerProcessCount", worker_count); 304 UMA_HISTOGRAM_COUNTS_100("Memory.WorkerProcessCount", worker_count);
297 305
298 int total_sample = static_cast<int>(aggregate_memory / 1000); 306 int total_sample = static_cast<int>(aggregate_memory / 1000);
299 UMA_HISTOGRAM_MEMORY_MB("Memory.Total", total_sample); 307 UMA_HISTOGRAM_MEMORY_MB("Memory.Total", total_sample);
300 } 308 }
OLDNEW
« no previous file with comments | « chrome/browser/memory_details.h ('k') | chrome/browser/resources/about_memory.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698