Skip to content

bs_mem module

Reports on memory usage:

  • mem_usage: prints the top n largest global items in memory
  • memory_display_top: prints the top n largest memory allocations since tracing started
  • memory_display_top_diffs: prints the top n largest memory allocations since the last snapshot.

memory_display_top(snapshot, key_type='lineno', limit=5)

prints out the lines with the top limit allocations of memory since tracemalloc.start()

Parameters:

Name Type Description Default
snapshot Snapshot

obtained from tracemalloc.take_snapshot()

required
key_type str

'lineno' gives file and line number; 'traceback' gives all

'lineno'
limit int | None

how many top allocations we want

5

Returns:

Type Description
None

just prints.

Examples:

>>> tracemalloc.start()
>>> .... execute ...
>>> snapshot = tracemalloc.take_snapshot()
>>> memory_display_top(snapshot)
Source code in bs_python_utils/bs_mem.py
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
def memory_display_top(
    snapshot: tracemalloc.Snapshot, key_type: str = "lineno", limit: int | None = 5
) -> None:
    """
    prints out the lines with the top `limit` allocations of memory since `tracemalloc.start()`

    Args:
        snapshot: obtained from tracemalloc.take_snapshot()
        key_type: 'lineno' gives file and line number; 'traceback' gives all
        limit: how many top allocations we want

    Returns:
        just prints.

    Examples:
       >>> tracemalloc.start()
       >>> .... execute ...
       >>> snapshot = tracemalloc.take_snapshot()
       >>> memory_display_top(snapshot)
    """

    top_stats = snapshot.statistics(key_type)

    print_stars(f"Top {limit} memory allocations")
    for index, stat in enumerate(top_stats[:limit], 1):
        frame = stat.traceback[0]
        print(
            "#%s: %s:%s: %.1f KiB"
            % (index, frame.filename, frame.lineno, stat.size / 1024)
        )
        line = linecache.getline(frame.filename, frame.lineno).strip()
        if line:
            print("    %s" % line)

    other = top_stats[limit:]
    if other:
        size = sum(stat.size for stat in other)
        print(f"{len(other)} other: {size / 1024:.1f} KiB")
    total = sum(stat.size for stat in top_stats)
    print("Total allocated size: %.1f KiB" % (total / 1024))

memory_display_top_diffs(snapshot1, snapshot2, key_type='lineno', limit=5)

prints out the lines with the top limit allocations between the two snapshots

Parameters:

Name Type Description Default
snapshot1 Snapshot

previous snapshot

required
snapshot2 Snapshot

new snapshot

required
key_type str

'lineno' gives file and line number; 'traceback' gives all

'lineno'
limit int

how many top allocations we want

5

Returns:

Type Description
None

just prints.

Examples:

>>> tracemalloc.start()
>>> .... execute ...
>>> snapshot1 = tracemalloc.take_snapshot()
>>> .... execute ...
>>> snapshot2 = tracemalloc.take_snapshot()
>>>  memory_display_top_diffs(snapshot1, snapshot2)
Source code in bs_python_utils/bs_mem.py
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
def memory_display_top_diffs(
    snapshot1: tracemalloc.Snapshot,
    snapshot2: tracemalloc.Snapshot,
    key_type: str = "lineno",
    limit: int = 5,
) -> None:
    """
    prints out the lines with the top `limit` allocations between the two snapshots

    Args:
        snapshot1: previous snapshot
        snapshot2: new snapshot
        key_type: 'lineno' gives file and line number; 'traceback' gives all
        limit: how many top allocations we want

    Returns:
        just prints.

    Examples:
       >>> tracemalloc.start()
       >>> .... execute ...
       >>> snapshot1 = tracemalloc.take_snapshot()
       >>> .... execute ...
       >>> snapshot2 = tracemalloc.take_snapshot()
       >>>  memory_display_top_diffs(snapshot1, snapshot2)

    """

    top_stats = snapshot2.compare_to(snapshot1, key_type)

    print_stars(f"Top {limit} new memory allocations")
    for index, stat in enumerate(top_stats[:limit], 1):
        frame = stat.traceback[0]
        print(
            "#%s: %s:%s: %.1f KiB"
            % (index, frame.filename, frame.lineno, stat.size / 1024)
        )
        line = linecache.getline(frame.filename, frame.lineno).strip()
        if line:
            print("    %s" % line)

    other = top_stats[limit:]
    if other:
        size = sum(stat.size for stat in other)
        print(f"{len(other)} other: {size / 1024:.1f} KiB")
    total = sum(stat.size for stat in top_stats)
    print("Total allocated size: %.1f KiB" % (total / 1024))

memory_usage(n=10)

prints the top n largest global items in memory

Parameters:

Name Type Description Default
n int | None

we report the size of the largest n global items

10

Returns:

Type Description
None

nothing.

Source code in bs_python_utils/bs_mem.py
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
def memory_usage(n: int | None = 10) -> None:
    """
    prints the top `n` largest global items in memory

    Args:
        n: we report the size of the largest `n` global items

    Returns:
        nothing.
    """
    memory_usage_by_variable = pd.DataFrame(
        {k: sys.getsizeof(v) for (k, v) in globals().items()}, index=["Size"]
    )
    memory_usage_by_variable = memory_usage_by_variable.T
    total_usage = _obj_size_fmt(memory_usage_by_variable["Size"].sum())
    memory_usage_by_variable = memory_usage_by_variable.sort_values(
        by="Size", ascending=False
    ).head(n)
    memory_usage_by_variable["Size"] = memory_usage_by_variable["Size"].apply(
        lambda x: _obj_size_fmt(x)
    )
    print_stars(
        f"Currently used memory = {total_usage}\n\t\t\t\t Top {n} global objects:"
    )
    print(memory_usage_by_variable)

    return