Add --memory-leak option

This commit is contained in:
nicolargo 2022-02-25 10:51:45 +01:00
parent 74a2e6bbe8
commit 1d222ff8a0
3 changed files with 53 additions and 8 deletions

View File

@ -97,7 +97,7 @@ def start(config, args):
# Load mode
global mode
if args.trace_malloc:
if args.trace_malloc or args.memory_leak:
tracemalloc.start()
start_duration = Counter()
@ -120,6 +120,17 @@ def start(config, args):
# Start the main loop
logger.debug("Glances started in {} seconds".format(start_duration.get()))
if args.stop_after:
logger.info('Glances will be stopped in ~{} seconds'.format(
args.stop_after * args.time * args.memory_leak * 2))
if args.memory_leak:
print('Memory leak detection, please wait...')
# First run without dump to fill the memory
mode.serve_n(args.stop_after)
# Then start the memory-leak loop
snapshot_begin = tracemalloc.take_snapshot()
if args.stdout_issue or args.stdout_apidoc:
# Serve once for issue/test mode
mode.serve_issue()
@ -127,10 +138,20 @@ def start(config, args):
# Serve forever
mode.serve_forever()
if args.trace_malloc:
if args.memory_leak:
snapshot_end = tracemalloc.take_snapshot()
snapshot_diff = snapshot_end.compare_to(snapshot_begin, 'filename')
memory_leak = sum([s.size_diff for s in snapshot_diff])
print("Memory comsumption for {} refreshs: {}KB (see log for details)".format(
args.stop_after,
memory_leak / 1000))
logger.info("Memory consumption (top 5):")
for stat in snapshot_diff[:5]:
logger.info(stat)
elif args.trace_malloc:
# See more options here: https://docs.python.org/3/library/tracemalloc.html
snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics("lineno")
top_stats = snapshot.statistics("filename")
print("[ Trace malloc - Top 10 ]")
for stat in top_stats[:10]:
print(stat)

View File

@ -427,7 +427,14 @@ Examples of use:
default=False,
action='store_true',
dest='trace_malloc',
help='test memory leak with tracemalloc (python 3.4 or higher needed)',
help='trace memory allocation and display it at the end of the process (python 3.4 or higher needed)',
)
parser.add_argument(
'--memory-leak',
default=False,
action='store_true',
dest='memory_leak',
help='test memory leak (python 3.4 or higher needed)',
)
parser.add_argument(
'--api-doc', default=None, action='store_true', dest='stdout_apidoc', help='display fields descriptions'
@ -685,11 +692,21 @@ Examples of use:
disable(self.args, 'hddtemp')
logger.debug("Sensors and HDDTemp are disabled")
if getattr(self.args, 'trace_malloc', True) and not PY3:
self.args.trace_malloc = False
logger.critical("trace_malloc is only available with Python 3")
if getattr(self.args, 'trace_malloc', True) and not (PY3 or self.is_standalone()):
logger.critical("Option --trace-malloc is only available with Python 3 and terminal mode")
sys.exit(2)
if getattr(self.args, 'memory_leak', True) and not (PY3 or self.is_standalone()):
logger.critical("Option --memory-leak is only available with Python 3 and terminal mode")
sys.exit(2)
else:
logger.info('Memory leak detection enabled')
self.args.quiet = True
if not self.args.stop_after:
self.args.stop_after = 60
self.args.time = 1
self.disable_history = True
# Let the plugins known the Glances mode
self.args.is_standalone = self.is_standalone()
self.args.is_client = self.is_client()

View File

@ -172,7 +172,14 @@ class GlancesStandalone(object):
else:
while self.__serve_once():
pass
self.end()
# self.end()
def serve_n(self, n=1):
"""Serve n time."""
for _ in range(n):
if not self.__serve_once():
break
# self.end()
def end(self):
"""End of the standalone CLI."""