# memorytop requires Python 3.4
#
# Usage: set PYTHONTRACEMALLOC=n in the environment of the hg invocation,
# where n>= is the number of frames to show in the backtrace. Put calls to
# memorytop in strategic places to show the current memory use by allocation
# site.

from __future__ import annotations

import gc
import tracemalloc


def memorytop(limit=10):
    gc.collect()
    snapshot = tracemalloc.take_snapshot()

    snapshot = snapshot.filter_traces(
        (
            tracemalloc.Filter(False, "<frozen importlib._bootstrap>"),
            tracemalloc.Filter(False, "<frozen importlib._bootstrap_external>"),
            tracemalloc.Filter(False, "<unknown>"),
        )
    )
    stats = snapshot.statistics('traceback')

    total = sum(stat.size for stat in stats)
    print("\nTotal allocated size: %.1f KiB\n" % (total / 1024))
    print("Lines with the biggest net allocations")
    for index, stat in enumerate(stats[:limit], 1):
        print(
            "#%d: %d objects using %.1f KiB"
            % (index, stat.count, stat.size / 1024)
        )
        for line in stat.traceback.format(most_recent_first=True):
            print('    ', line)

    other = stats[limit:]
    if other:
        size = sum(stat.size for stat in other)
        count = sum(stat.count for stat in other)
        print(
            "%s other: %d objects using %.1f KiB"
            % (len(other), count, size / 1024)
        )
    print()
