summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/process_util.h10
-rw-r--r--base/process_util_linux.cc15
-rw-r--r--base/process_util_mac.mm12
-rw-r--r--base/process_util_win.cc23
-rw-r--r--chrome/browser/task_manager.cc56
-rw-r--r--chrome/browser/task_manager.h19
6 files changed, 102 insertions, 33 deletions
diff --git a/base/process_util.h b/base/process_util.h
index ec3510a..b8bcfd4 100644
--- a/base/process_util.h
+++ b/base/process_util.h
@@ -481,10 +481,12 @@ class ProcessMetrics {
size_t GetWorkingSetSize() const;
// Returns the peak working set size, in bytes.
size_t GetPeakWorkingSetSize() const;
- // Returns private usage, in bytes. Private bytes is the amount
- // of memory currently allocated to a process that cannot be shared.
- // Note: returns 0 on unsupported OSes: prior to XP SP2.
- size_t GetPrivateBytes() const;
+ // Returns private and sharedusage, in bytes. Private bytes is the amount of
+ // memory currently allocated to a process that cannot be shared. Returns
+ // false on platform specific error conditions. Note: |private_bytes|
+ // returns 0 on unsupported OSes: prior to XP SP2.
+ bool GetMemoryBytes(size_t* private_bytes,
+ size_t* shared_bytes);
// Fills a CommittedKBytes with both resident and paged
// memory usage as per definition of CommittedBytes.
void GetCommittedKBytes(CommittedKBytes* usage) const;
diff --git a/base/process_util_linux.cc b/base/process_util_linux.cc
index 0a2cc0d..ee44638 100644
--- a/base/process_util_linux.cc
+++ b/base/process_util_linux.cc
@@ -244,10 +244,19 @@ size_t ProcessMetrics::GetPeakWorkingSetSize() const {
return 0;
}
-size_t ProcessMetrics::GetPrivateBytes() const {
+bool ProcessMetrics::GetMemoryBytes(size_t* private_bytes,
+ size_t* shared_bytes) {
WorkingSetKBytes ws_usage;
- GetWorkingSetKBytes(&ws_usage);
- return ws_usage.priv << 10;
+ if (!GetWorkingSetKBytes(&ws_usage))
+ return false;
+
+ if (private_bytes)
+ *private_bytes = ws_usage.priv << 10;
+
+ if (shared_bytes)
+ *shared_bytes = ws_usage.shared * 1024;
+
+ return true;
}
// Private and Shared working set sizes are obtained from /proc/<pid>/smaps.
diff --git a/base/process_util_mac.mm b/base/process_util_mac.mm
index f119e78..9fcc43c 100644
--- a/base/process_util_mac.mm
+++ b/base/process_util_mac.mm
@@ -222,10 +222,16 @@ size_t ProcessMetrics::GetPeakWorkingSetSize() const {
return 0;
}
-size_t ProcessMetrics::GetPrivateBytes() const {
- return 0;
+// OSX appears to use a different system to get its memory.
+bool ProcessMetrics::GetMemoryBytes(size_t* private_bytes,
+ size_t* shared_bytes) {
+ if (private_bytes)
+ *private_bytes = 0;
+ if (shared_bytes)
+ *shared_bytes = 0;
+ return true;
}
-
+
void ProcessMetrics::GetCommittedKBytes(CommittedKBytes* usage) const {
}
diff --git a/base/process_util_win.cc b/base/process_util_win.cc
index 8df8de5..2eb73ca 100644
--- a/base/process_util_win.cc
+++ b/base/process_util_win.cc
@@ -515,18 +515,29 @@ size_t ProcessMetrics::GetPeakWorkingSetSize() const {
return 0;
}
-size_t ProcessMetrics::GetPrivateBytes() const {
+bool ProcessMetrics::GetMemoryBytes(size_t* private_bytes,
+ size_t* shared_bytes) {
// PROCESS_MEMORY_COUNTERS_EX is not supported until XP SP2.
// GetProcessMemoryInfo() will simply fail on prior OS. So the requested
// information is simply not available. Hence, we will return 0 on unsupported
// OSes. Unlike most Win32 API, we don't need to initialize the "cb" member.
PROCESS_MEMORY_COUNTERS_EX pmcx;
- if (GetProcessMemoryInfo(process_,
- reinterpret_cast<PROCESS_MEMORY_COUNTERS*>(&pmcx),
- sizeof(pmcx))) {
- return pmcx.PrivateUsage;
+ if (private_bytes &&
+ GetProcessMemoryInfo(process_,
+ reinterpret_cast<PROCESS_MEMORY_COUNTERS*>(&pmcx),
+ sizeof(pmcx))) {
+ *private_bytes = pmcx.PrivateUsage;
}
- return 0;
+
+ if (shared_bytes) {
+ WorkingSetKBytes ws_usage;
+ if (!GetWorkingSetKBytes(&ws_usage))
+ return false;
+
+ *shared_bytes = ws_usage.shared * 1024;
+ }
+
+ return true;
}
void ProcessMetrics::GetCommittedKBytes(CommittedKBytes* usage) const {
diff --git a/chrome/browser/task_manager.cc b/chrome/browser/task_manager.cc
index a604b70..1d2907a 100644
--- a/chrome/browser/task_manager.cc
+++ b/chrome/browser/task_manager.cc
@@ -404,25 +404,34 @@ double TaskManagerModel::GetCPUUsage(TaskManager::Resource* resource) const {
}
bool TaskManagerModel::GetPrivateMemory(int index, size_t* result) const {
- *result = 0;
- base::ProcessMetrics* process_metrics;
- if (!GetProcessMetricsForRow(index, &process_metrics))
- return false;
- *result = process_metrics->GetPrivateBytes();
- if (*result == 0)
- return false;
+ base::ProcessHandle handle = resources_[index]->GetProcess();
+ MemoryUsageMap::const_iterator iter = memory_usage_map_.find(handle);
+ if (iter == memory_usage_map_.end()) {
+ std::pair<size_t, size_t> usage;
+ if (!GetAndCacheMemoryMetrics(handle, &usage))
+ return false;
+
+ *result = usage.first;
+ } else {
+ *result = iter->second.first;
+ }
+
return true;
}
bool TaskManagerModel::GetSharedMemory(int index, size_t* result) const {
- *result = 0;
- base::ProcessMetrics* process_metrics;
- if (!GetProcessMetricsForRow(index, &process_metrics))
- return false;
- base::WorkingSetKBytes ws_usage;
- if (!process_metrics->GetWorkingSetKBytes(&ws_usage))
- return false;
- *result = ws_usage.shared * 1024;
+ base::ProcessHandle handle = resources_[index]->GetProcess();
+ MemoryUsageMap::const_iterator iter = memory_usage_map_.find(handle);
+ if (iter == memory_usage_map_.end()) {
+ std::pair<size_t, size_t> usage;
+ if (!GetAndCacheMemoryMetrics(handle, &usage))
+ return false;
+
+ *result = usage.second;
+ } else {
+ *result = iter->second.second;
+ }
+
return true;
}
@@ -718,6 +727,9 @@ void TaskManagerModel::Refresh() {
cpu_usage_map_[process] = metrics_iter->second->GetCPUUsage();
}
+ // Clear the memory values so they can be querried lazily.
+ memory_usage_map_.clear();
+
// Compute the new network usage values.
displayed_network_usage_map_.clear();
for (ResourceValueMap::iterator iter = current_byte_count_map_.begin();
@@ -952,3 +964,17 @@ void TaskManager::OpenAboutMemory() {
browser->window()->Show();
}
}
+
+bool TaskManagerModel::GetAndCacheMemoryMetrics(
+ base::ProcessHandle handle,
+ std::pair<size_t, size_t>* usage) const {
+ MetricsMap::const_iterator iter = metrics_map_.find(handle);
+ if (iter == metrics_map_.end())
+ return false;
+
+ if (!iter->second->GetMemoryBytes(&usage->first, &usage->second))
+ return false;
+
+ memory_usage_map_.insert(std::make_pair(handle, *usage));
+ return true;
+}
diff --git a/chrome/browser/task_manager.h b/chrome/browser/task_manager.h
index 88b452d..6f807b8 100644
--- a/chrome/browser/task_manager.h
+++ b/chrome/browser/task_manager.h
@@ -300,6 +300,8 @@ class TaskManagerModel : public URLRequestJobTracker::JobObserver,
typedef std::map<base::ProcessHandle, base::ProcessMetrics*> MetricsMap;
typedef std::map<base::ProcessHandle, double> CPUUsageMap;
typedef std::map<TaskManager::Resource*, int64> ResourceValueMap;
+ typedef std::map<base::ProcessHandle,
+ std::pair<size_t, size_t> > MemoryUsageMap;
// Updates the values for all rows.
void Refresh();
@@ -328,11 +330,13 @@ class TaskManagerModel : public URLRequestJobTracker::JobObserver,
double GetCPUUsage(TaskManager::Resource* resource) const;
// Gets the private memory (in bytes) that should be displayed for the passed
- // resource index.
+ // resource index. Caches the result since this calculation can take time on
+ // some platforms.
bool GetPrivateMemory(int index, size_t* result) const;
// Gets the shared memory (in bytes) that should be displayed for the passed
- // resource index.
+ // resource index. Caches the result since this calculation can take time on
+ // some platforms.
bool GetSharedMemory(int index, size_t* result) const;
// Gets the physical memory (in bytes) that should be displayed for the passed
@@ -355,6 +359,11 @@ class TaskManagerModel : public URLRequestJobTracker::JobObserver,
// displayed in the task manager's memory cell.
std::wstring GetMemCellText(int64 number) const;
+ // Looks up the data for |handle| and puts it in the mutable cache
+ // |memory_usage_map_|.
+ bool GetAndCacheMemoryMetrics(base::ProcessHandle handle,
+ std::pair<size_t, size_t>* usage) const;
+
// The list of providers to the task manager. They are ref counted.
ResourceProviderList providers_;
@@ -383,6 +392,12 @@ class TaskManagerModel : public URLRequestJobTracker::JobObserver,
// A map that contains the CPU usage (in %) for a process since last refresh.
CPUUsageMap cpu_usage_map_;
+ // A map that contains the private/shared memory usage of the process. We
+ // cache this because the same APIs are called on linux and windows, and
+ // because the linux call takes >10ms to complete. This cache is cleared on
+ // every Refresh().
+ mutable MemoryUsageMap memory_usage_map_;
+
ObserverList<TaskManagerModelObserver> observer_list_;
// Whether we are currently in the process of updating.