123 lines
4.2 KiB
Python
123 lines
4.2 KiB
Python
|
#!/usr/bin/env python
|
||
|
#
|
||
|
# Copyright (c) 2013 The Chromium Authors. All rights reserved.
|
||
|
# Use of this source code is governed by a BSD-style license that can be
|
||
|
# found in the LICENSE file.
|
||
|
|
||
|
import re
|
||
|
import sys
|
||
|
|
||
|
from sets import Set
|
||
|
|
||
|
|
||
|
_ENTRIES = [
|
||
|
('Total', '.* r... .*'),
|
||
|
('Read-only', '.* r--. .*'),
|
||
|
('Read-write', '.* rw.. .*'),
|
||
|
('Executable', '.* ..x. .*'),
|
||
|
('Anonymous total', '.* .... .* .*other=[0-9]+ ($|.*chromium:.*)'),
|
||
|
('Anonymous read-write', '.* rw.. .* .*other=[0-9]+ ($|.*chromium:.*)'),
|
||
|
('Anonymous executable (JIT\'ed code)', '.* ..x. .* shared_other=[0-9]+ $'),
|
||
|
('File total', '.* .... .* /.*'),
|
||
|
('File read-write', '.* rw.. .* /.*'),
|
||
|
('File executable', '.* ..x. .* /.*'),
|
||
|
('chromium mmap', '.* r... .*chromium:.*'),
|
||
|
('chromium TransferBuffer', '.* r... .*chromium:.*CreateTransferBuffer.*'),
|
||
|
('Galaxy Nexus GL driver', '.* r... .*pvrsrvkm.*'),
|
||
|
('Dalvik', '.* rw.. .* /.*dalvik.*'),
|
||
|
('Dalvik heap', '.* rw.. .* /.*dalvik-heap.*'),
|
||
|
('Native heap (jemalloc)', '.* r... .* /.*jemalloc.*'),
|
||
|
('System heap', '.* r... .* \\[heap\\]'),
|
||
|
('Ashmem', '.* rw.. .* /dev/ashmem .*'),
|
||
|
('libchromeview.so total', '.* r... .* /.*libchromeview.so'),
|
||
|
('libchromeview.so read-only', '.* r--. .* /.*libchromeview.so'),
|
||
|
('libchromeview.so read-write', '.* rw-. .* /.*libchromeview.so'),
|
||
|
('libchromeview.so executable', '.* r.x. .* /.*libchromeview.so'),
|
||
|
]
|
||
|
|
||
|
|
||
|
def _CollectMemoryStats(memdump, region_filters):
|
||
|
processes = []
|
||
|
mem_usage_for_regions = None
|
||
|
regexps = {}
|
||
|
for region_filter in region_filters:
|
||
|
regexps[region_filter] = re.compile(region_filter)
|
||
|
for line in memdump:
|
||
|
if 'PID=' in line:
|
||
|
mem_usage_for_regions = {}
|
||
|
processes.append(mem_usage_for_regions)
|
||
|
continue
|
||
|
matched_regions = Set([])
|
||
|
for region_filter in region_filters:
|
||
|
if regexps[region_filter].match(line.rstrip('\r\n')):
|
||
|
matched_regions.add(region_filter)
|
||
|
if not region_filter in mem_usage_for_regions:
|
||
|
mem_usage_for_regions[region_filter] = {
|
||
|
'private_unevictable': 0,
|
||
|
'private': 0,
|
||
|
'shared_app': 0.0,
|
||
|
'shared_other_unevictable': 0,
|
||
|
'shared_other': 0,
|
||
|
}
|
||
|
for matched_region in matched_regions:
|
||
|
mem_usage = mem_usage_for_regions[matched_region]
|
||
|
for key in mem_usage:
|
||
|
for token in line.split(' '):
|
||
|
if (key + '=') in token:
|
||
|
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
|
||
|
|
||
|
|
||
|
def _ConvertMemoryField(field):
|
||
|
return str(field / (1024.0 * 1024))
|
||
|
|
||
|
|
||
|
def _DumpCSV(processes_stats):
|
||
|
total_map = {}
|
||
|
i = 0
|
||
|
for process in processes_stats:
|
||
|
i += 1
|
||
|
print (',Process ' + str(i) + ',private,private_unevictable,shared_app,' +
|
||
|
'shared_other,shared_other_unevictable,')
|
||
|
for (k, v) in _ENTRIES:
|
||
|
if not v in process:
|
||
|
print ',' + k + ',0,0,0,0,'
|
||
|
continue
|
||
|
if not v in total_map:
|
||
|
total_map[v] = {'resident':0, 'unevictable':0}
|
||
|
total_map[v]['resident'] += (process[v]['private'] +
|
||
|
process[v]['shared_app'])
|
||
|
total_map[v]['unevictable'] += process[v]['private_unevictable']
|
||
|
print (
|
||
|
',' + k + ',' +
|
||
|
_ConvertMemoryField(process[v]['private']) + ',' +
|
||
|
_ConvertMemoryField(process[v]['private_unevictable']) + ',' +
|
||
|
_ConvertMemoryField(process[v]['shared_app']) + ',' +
|
||
|
_ConvertMemoryField(process[v]['shared_other']) + ',' +
|
||
|
_ConvertMemoryField(process[v]['shared_other_unevictable']) + ','
|
||
|
)
|
||
|
print ''
|
||
|
|
||
|
for (k, v) in _ENTRIES:
|
||
|
if not v in total_map:
|
||
|
print ',' + k + ',0,0,'
|
||
|
continue
|
||
|
print (',' + k + ',' + _ConvertMemoryField(total_map[v]['resident']) + ',' +
|
||
|
_ConvertMemoryField(total_map[v]['unevictable']) + ',')
|
||
|
print ''
|
||
|
|
||
|
|
||
|
def main(argv):
|
||
|
_DumpCSV(_CollectMemoryStats(sys.stdin, [value for (key, value) in _ENTRIES]))
|
||
|
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
main(sys.argv)
|