summaryrefslogtreecommitdiffstats
path: root/tools/android
diff options
context:
space:
mode:
authorpliard@chromium.org <pliard@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-25 16:40:08 +0000
committerpliard@chromium.org <pliard@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-25 16:40:08 +0000
commit750488e4ed4bba0772a8e997b6e89948a5ce7b7f (patch)
tree600ba0510d26d29ce6a90311a6c494bc397364db /tools/android
parent073ce9188d9218f0a635118530a4bca6ab07d3ca (diff)
downloadchromium_src-750488e4ed4bba0772a8e997b6e89948a5ce7b7f.zip
chromium_src-750488e4ed4bba0772a8e997b6e89948a5ce7b7f.tar.gz
chromium_src-750488e4ed4bba0772a8e997b6e89948a5ce7b7f.tar.bz2
Add suport for total stats to memdump for more than 2 processes.
The 'shared_app' field part of the memdump output is now broken down to include the number of pages (* PAGE_SIZE) mapped for each process being analyzed, e.g.: 56419000-56619000 rw-s private=0 shared_app=[1183744,0] shared_other=0 /dev/ashmem (deleted) In the example above, the i-th element of shared_app contains the number of pages (* PAGE_SIZE) that are mapped in i+2 processes (only among the processes that are provided on the command line). R=digit@chromium.org, qsr@chromium.org Review URL: https://codereview.chromium.org/17366005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@208505 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/android')
-rw-r--r--tools/android/memdump/memdump.cc60
-rwxr-xr-xtools/android/memdump/memreport.py17
2 files changed, 47 insertions, 30 deletions
diff --git a/tools/android/memdump/memdump.cc b/tools/android/memdump/memdump.cc
index 70dbace..e4f20d1 100644
--- a/tools/android/memdump/memdump.cc
+++ b/tools/android/memdump/memdump.cc
@@ -48,8 +48,10 @@ struct MemoryMap {
uint start_address;
uint end_address;
int private_count;
- int app_shared_count;
int other_shared_count;
+ // app_shared_counts[i] contains the number of pages mapped in i+2 processes
+ // (only among the processes that are being analyzed).
+ std::vector<int> app_shared_counts;
std::vector<PageInfo> committed_pages;
};
@@ -204,7 +206,7 @@ void FillPFNMaps(const std::vector<ProcessMemory>& processes_memory,
}
}
-// Sets the private_count/app_shared_count/other_shared_count fields of the
+// Sets the private_count/app_shared_counts/other_shared_count fields of the
// provided memory maps for each process.
void ClassifyPages(std::vector<ProcessMemory>* processes_memory) {
std::vector<PFNMap> pfn_maps(processes_memory->size());
@@ -220,6 +222,8 @@ void ClassifyPages(std::vector<ProcessMemory>* processes_memory) {
for (std::vector<MemoryMap>::iterator it = memory_maps->begin();
it != memory_maps->end(); ++it) {
MemoryMap* const memory_map = &*it;
+ const size_t processes_count = processes_memory->size();
+ memory_map->app_shared_counts.resize(processes_count - 1, 0);
const std::vector<PageInfo>& pages = memory_map->committed_pages;
for (std::vector<PageInfo>::const_iterator it = pages.begin();
it != pages.end(); ++it) {
@@ -240,7 +244,7 @@ void ClassifyPages(std::vector<ProcessMemory>* processes_memory) {
// See if the current physical page is also mapped in the other
// processes that are being analyzed.
int times_mapped = 0;
- bool mapped_in_multiple_processes = false;
+ int mapped_in_processes_count = 0;
for (std::vector<PFNMap>::const_iterator it = pfn_maps.begin();
it != pfn_maps.end(); ++it) {
const PFNMap& pfn_map = *it;
@@ -248,15 +252,15 @@ void ClassifyPages(std::vector<ProcessMemory>* processes_memory) {
page_frame_number);
if (found_it == pfn_map.end())
continue;
- if (times_mapped)
- mapped_in_multiple_processes = true;
+ ++mapped_in_processes_count;
times_mapped += found_it->second;
}
if (times_mapped == page_info.times_mapped) {
// The physical page is only mapped in the processes that are being
// analyzed.
- if (mapped_in_multiple_processes) {
- ++memory_map->app_shared_count;
+ if (mapped_in_processes_count > 1) {
+ // The physical page is mapped in multiple processes.
+ ++memory_map->app_shared_counts[mapped_in_processes_count - 2];
} else {
// The physical page is mapped multiple times in the same process.
++memory_map->private_count;
@@ -269,9 +273,22 @@ void ClassifyPages(std::vector<ProcessMemory>* processes_memory) {
}
}
+void AppendAppSharedField(const std::vector<int>& app_shared_counts,
+ std::string* out) {
+ out->append("[");
+ for (std::vector<int>::const_iterator it = app_shared_counts.begin();
+ it != app_shared_counts.end(); ++it) {
+ out->append(base::IntToString(*it * PAGE_SIZE));
+ if (it + 1 != app_shared_counts.end())
+ out->append(",");
+ }
+ out->append("]");
+}
+
void DumpProcessesMemoryMaps(
const std::vector<ProcessMemory>& processes_memory) {
std::string buf;
+ std::string app_shared_buf;
for (std::vector<ProcessMemory>::const_iterator it = processes_memory.begin();
it != processes_memory.end(); ++it) {
const ProcessMemory& process_memory = *it;
@@ -280,12 +297,14 @@ void DumpProcessesMemoryMaps(
for (std::vector<MemoryMap>::const_iterator it = memory_maps.begin();
it != memory_maps.end(); ++it) {
const MemoryMap& memory_map = *it;
+ app_shared_buf.clear();
+ AppendAppSharedField(memory_map.app_shared_counts, &app_shared_buf);
base::SStringPrintf(
- &buf, "%x-%x %s private=%d shared_app=%d shared_other=%d %s\n",
+ &buf, "%x-%x %s private=%d shared_app=%s shared_other=%d %s\n",
memory_map.start_address,
memory_map.end_address, memory_map.flags.c_str(),
memory_map.private_count * PAGE_SIZE,
- memory_map.app_shared_count * PAGE_SIZE,
+ app_shared_buf.c_str(),
memory_map.other_shared_count * PAGE_SIZE,
memory_map.name.c_str());
std::cout << buf;
@@ -295,26 +314,32 @@ void DumpProcessesMemoryMaps(
void DumpProcessesMemoryMapsInShortFormat(
const std::vector<ProcessMemory>& processes_memory) {
- std::string buf;
const int KB_PER_PAGE = PAGE_SIZE >> 10;
+ std::vector<int> totals_app_shared(processes_memory.size());
+ std::string buf;
std::cout << "pid\tprivate\t\tshared_app\tshared_other (KB)\n";
for (std::vector<ProcessMemory>::const_iterator it = processes_memory.begin();
it != processes_memory.end(); ++it) {
const ProcessMemory& process_memory = *it;
- long total_private = 0, total_app_shared = 0, total_other_shared = 0;
+ std::fill(totals_app_shared.begin(), totals_app_shared.end(), 0);
+ int total_private = 0, total_other_shared = 0;
const std::vector<MemoryMap>& memory_maps = process_memory.memory_maps;
for (std::vector<MemoryMap>::const_iterator it = memory_maps.begin();
it != memory_maps.end(); ++it) {
const MemoryMap& memory_map = *it;
total_private += memory_map.private_count;
- total_app_shared += memory_map.app_shared_count;
+ for (size_t i = 0; i < memory_map.app_shared_counts.size(); ++i)
+ totals_app_shared[i] += memory_map.app_shared_counts[i];
total_other_shared += memory_map.other_shared_count;
}
+ double total_app_shared = 0;
+ for (size_t i = 0; i < totals_app_shared.size(); ++i)
+ total_app_shared += static_cast<double>(totals_app_shared[i]) / (i + 2);
base::SStringPrintf(
&buf, "%d\t%d\t\t%d\t\t%d\n",
process_memory.pid,
total_private * KB_PER_PAGE,
- total_app_shared * KB_PER_PAGE,
+ static_cast<int>(total_app_shared) * KB_PER_PAGE,
total_other_shared * KB_PER_PAGE);
std::cout << buf;
}
@@ -373,15 +398,6 @@ int main(int argc, char** argv) {
pids.push_back(pid);
}
- // Currently memdump does not count pages shared by more than
- // 2 browser and render processes correctly.
- // Bail out early in -a mode if more than 2 pids are given to avoid
- // confusion.
- if (short_output && pids.size() > 2) {
- LOG(ERROR) << "Sorry, '-a' cannot be used for more than 2 PIDs.";
- return EXIT_FAILURE;
- }
-
std::vector<ProcessMemory> processes_memory(pids.size());
{
int page_count_fd = open("/proc/kpagecount", O_RDONLY);
diff --git a/tools/android/memdump/memreport.py b/tools/android/memdump/memreport.py
index 62b3ac4..02e080d 100755
--- a/tools/android/memdump/memreport.py
+++ b/tools/android/memdump/memreport.py
@@ -52,7 +52,7 @@ def _CollectMemoryStats(memdump, region_filters):
if not region_filter in mem_usage_for_regions:
mem_usage_for_regions[region_filter] = {
'private': 0,
- 'shared_app': 0,
+ 'shared_app': 0.0,
'shared_other': 0,
}
for matched_region in matched_regions:
@@ -60,7 +60,13 @@ def _CollectMemoryStats(memdump, region_filters):
for key in mem_usage:
for token in line.split(' '):
if key in token:
- mem_usage[key] += int(token.split('=')[1])
+ field = token.split('=')[1]
+ if key != 'shared_app':
+ mem_usage[key] += int(field)
+ else: # shared_app=[\d,\d...]
+ array = eval(field)
+ for i in xrange(len(array)):
+ mem_usage[key] += float(array[i]) / (i + 2)
break
return processes
@@ -81,17 +87,12 @@ def _DumpCSV(processes_stats):
continue
if not v in total_map:
total_map[v] = 0
- total_map[v] += process[v]['private'] + (
- process[v]['shared_app'] / len(processes_stats))
+ total_map[v] += process[v]['private'] + process[v]['shared_app']
print ',' + k + ',' + _ConvertMemoryField(process[v]['private']) + ',' + (
_ConvertMemoryField(process[v]['shared_app']) + ',' + (
_ConvertMemoryField(process[v]['shared_other'])) + ',')
print ''
- if len(processes_stats) > 2:
- print >>sys.stderr, (
- 'Total stats are not supported yet with more than two processes.')
- return
for (k, v) in _ENTRIES:
if not v in total_map:
print ',' + k + ',0,0'