Update memory reporting script
This commit is contained in:
parent
a52c45bd08
commit
a026cd91fe
1 changed files with 100 additions and 51 deletions
151
test/meminfo.py
151
test/meminfo.py
|
@ -42,24 +42,104 @@ def get_mappings(pid):
|
||||||
return mappings
|
return mappings
|
||||||
|
|
||||||
|
|
||||||
def extract_mappings(maps, select_func, group_func):
|
def rss_extractor(m):
|
||||||
|
if "Rss" in m and is_int(m["Rss"]):
|
||||||
|
return int(m["Rss"])
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
def private_extractor(m):
|
||||||
|
result = 0
|
||||||
|
if "Private_Clean" in m and is_int(m["Private_Clean"]):
|
||||||
|
result += int(m["Private_Clean"])
|
||||||
|
if "Private_Dirty" in m and is_int(m["Private_Dirty"]):
|
||||||
|
result += int(m["Private_Dirty"])
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def shared_extractor(m):
|
||||||
|
result = 0
|
||||||
|
if "Shared_Clean" in m and is_int(m["Shared_Clean"]):
|
||||||
|
result += int(m["Shared_Clean"])
|
||||||
|
if "Shared_Dirty" in m and is_int(m["Shared_Dirty"]):
|
||||||
|
result += int(m["Shared_Dirty"])
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def extract_mappings(maps, select_func, group_func, val_func=rss_extractor):
|
||||||
parts = {}
|
parts = {}
|
||||||
for m in maps:
|
for m in maps:
|
||||||
if "Rss" in m and is_int(m["Rss"]) and m["Rss"] > 0 and select_func(m):
|
if select_func(m) and val_func(m):
|
||||||
group = group_func(m)
|
group = group_func(m)
|
||||||
if group not in parts:
|
if group not in parts:
|
||||||
parts[group] = 0
|
parts[group] = 0
|
||||||
parts[group] += m["Rss"]
|
parts[group] += val_func(m)
|
||||||
parts = parts.items()
|
parts = parts.items()
|
||||||
parts.sort(key=lambda p: -p[1])
|
parts.sort(key=lambda p: -p[1])
|
||||||
total = sum([p[1] for p in parts])
|
total = sum([p[1] for p in parts])
|
||||||
return total, parts
|
return total, parts
|
||||||
|
|
||||||
|
|
||||||
def print_histogram(name, maps, extractor_func, detailed):
|
def extract_total(maps, args):
|
||||||
total, histogram = extractor_func(maps)
|
return extract_mappings(maps,
|
||||||
|
lambda m: True,
|
||||||
|
lambda m: "Total",
|
||||||
|
rss_extractor)
|
||||||
|
|
||||||
|
|
||||||
|
def extract_total_shared(maps, args):
|
||||||
|
return extract_mappings(maps,
|
||||||
|
lambda m: True,
|
||||||
|
lambda m: "Shared",
|
||||||
|
shared_extractor)
|
||||||
|
|
||||||
|
|
||||||
|
def extract_total_private(maps, args):
|
||||||
|
return extract_mappings(maps,
|
||||||
|
lambda m: True,
|
||||||
|
lambda m: "Private",
|
||||||
|
private_extractor)
|
||||||
|
|
||||||
|
|
||||||
|
def extract_code(maps, args):
|
||||||
|
return extract_mappings(maps,
|
||||||
|
lambda m: "ex" in m["VmFlags"],
|
||||||
|
lambda m: m["path"],
|
||||||
|
private_extractor if args.private else rss_extractor)
|
||||||
|
|
||||||
|
|
||||||
|
def extract_heap(maps, args):
|
||||||
|
return extract_mappings(maps,
|
||||||
|
lambda m: m["path"] == "[heap]",
|
||||||
|
lambda m: m["path"],
|
||||||
|
private_extractor if args.private else rss_extractor)
|
||||||
|
|
||||||
|
|
||||||
|
def extract_stack(maps, args):
|
||||||
|
return extract_mappings(maps,
|
||||||
|
lambda m: m["path"] == "[stack]",
|
||||||
|
lambda m: m["path"],
|
||||||
|
private_extractor if args.private else rss_extractor)
|
||||||
|
|
||||||
|
|
||||||
|
def extract_mapped_files(maps, args):
|
||||||
|
return extract_mappings(maps,
|
||||||
|
lambda m: "/" in m["path"] and "ex" not in m["VmFlags"],
|
||||||
|
lambda m: m["path"],
|
||||||
|
private_extractor if args.private else rss_extractor)
|
||||||
|
|
||||||
|
|
||||||
|
def extract_other(maps, args):
|
||||||
|
return extract_mappings(maps,
|
||||||
|
lambda m: "/" not in m["path"] and m["path"] != "[stack]" and m["path"] != "[heap]" and "ex" not in m["VmFlags"],
|
||||||
|
lambda m: m["path"],
|
||||||
|
private_extractor if args.private else rss_extractor)
|
||||||
|
|
||||||
|
|
||||||
|
def print_histogram(name, maps, extractor_func, args):
|
||||||
|
total, histogram = extractor_func(maps, args)
|
||||||
print "{}: {:,} B".format(name, total)
|
print "{}: {:,} B".format(name, total)
|
||||||
if not detailed:
|
if not args.detailed:
|
||||||
return
|
return
|
||||||
max_size_str_len = 0
|
max_size_str_len = 0
|
||||||
for item, size in histogram:
|
for item, size in histogram:
|
||||||
|
@ -69,59 +149,28 @@ def print_histogram(name, maps, extractor_func, detailed):
|
||||||
print " * {}{} B: {}".format(" " * padding, size_str, item)
|
print " * {}{} B: {}".format(" " * padding, size_str, item)
|
||||||
|
|
||||||
|
|
||||||
def extract_total(maps):
|
def show_mem_info(args):
|
||||||
return extract_mappings(maps,
|
maps = get_mappings(args.pid)
|
||||||
lambda m: True,
|
print_histogram("Total", maps, extract_total, args)
|
||||||
lambda m: "Total")
|
print_histogram("Shared", maps, extract_total_shared, args)
|
||||||
|
print_histogram("Private", maps, extract_total_private, args)
|
||||||
|
print "Breakdown:"
|
||||||
def extract_code_size(maps):
|
print_histogram("* Heap", maps, extract_heap, args)
|
||||||
return extract_mappings(maps,
|
print_histogram("* Stack", maps, extract_stack, args)
|
||||||
lambda m: "ex" in m["VmFlags"],
|
print_histogram("* Memory mapped files", maps, extract_mapped_files, args)
|
||||||
lambda m: m["path"])
|
print_histogram("* Executable code", maps, extract_code, args)
|
||||||
|
print_histogram("* Other", maps, extract_other, args)
|
||||||
|
|
||||||
def extract_heap_size(maps):
|
|
||||||
return extract_mappings(maps,
|
|
||||||
lambda m: m["path"] == "[heap]",
|
|
||||||
lambda m: m["path"])
|
|
||||||
|
|
||||||
|
|
||||||
def extract_stack_size(maps):
|
|
||||||
return extract_mappings(maps,
|
|
||||||
lambda m: m["path"] == "[stack]",
|
|
||||||
lambda m: m["path"])
|
|
||||||
|
|
||||||
|
|
||||||
def extract_mapped_files(maps):
|
|
||||||
return extract_mappings(maps,
|
|
||||||
lambda m: "/" in m["path"] and "ex" not in m["VmFlags"],
|
|
||||||
lambda m: m["path"])
|
|
||||||
|
|
||||||
|
|
||||||
def extract_other(maps):
|
|
||||||
return extract_mappings(maps,
|
|
||||||
lambda m: "/" not in m["path"] and m["path"] != "[stack]" and m["path"] != "[heap]" and "ex" not in m["VmFlags"],
|
|
||||||
lambda m: m["path"])
|
|
||||||
|
|
||||||
|
|
||||||
def show_mem_info(pid, detailed):
|
|
||||||
maps = get_mappings(pid)
|
|
||||||
print_histogram("Total", maps, extract_total, detailed)
|
|
||||||
print_histogram("* Heap", maps, extract_heap_size, detailed)
|
|
||||||
print_histogram("* Stack", maps, extract_stack_size, detailed)
|
|
||||||
print_histogram("* Memory mapped files", maps, extract_mapped_files, detailed)
|
|
||||||
print_histogram("* Executable code", maps, extract_code_size, detailed)
|
|
||||||
print_histogram("* Other", maps, extract_other, detailed)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(description="Prints the memory allocation information of a process.")
|
parser = argparse.ArgumentParser(description="Prints the memory allocation information of a process.")
|
||||||
parser.add_argument("--detailed", action="store_true", help="Show a breakdown for each category.")
|
parser.add_argument("--detailed", action="store_true", help="Show a breakdown for each category.")
|
||||||
|
parser.add_argument("--private", action="store_true", help="Do not take int account memory shared with other processes.")
|
||||||
parser.add_argument("pid", help="PID of the process whose memory is to be analyzed.", type=int)
|
parser.add_argument("pid", help="PID of the process whose memory is to be analyzed.", type=int)
|
||||||
parser.set_defaults(detailed=False)
|
parser.set_defaults(detailed=False)
|
||||||
|
parser.set_defaults(private=False)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
show_mem_info(args.pid, args.detailed)
|
show_mem_info(args)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
Loading…
Reference in a new issue