# tracemalloc-获取内存分配状态

# 概述

Python内置了gc​模块,通过gc​模块,我们可以以比较低级的方式获取程序的内存使用情况。但是gc​只能获取内存使用情况而无法获取更详细的信息:例如到底是哪行代码分配了这些对象。

Python3.4推出了新的内置模块用于解决这些需求-tracemalloc​,同事可以用于检测内存泄漏、性能瓶颈等问题。它可以记录 Python 程序中分配的所有内存块,并提供一些有用的 API 来分析内存分配情况。

tracemalloc​ 模块主要有以下两个方法:

  • tracemalloc.start([nframe])​:开始跟踪内存分配情况。参数 nframe​ 指定要记录的堆栈帧数,默认为 1。
  • tracemalloc.stop()​:停止跟踪内存分配情况。

此外,还有以下几个用于分析和显示内存分配情况的函数:

  • tracemalloc.get_traced_memory()​:返回当前跟踪的内存分配情况,包括已分配和未释放的内存量。
  • tracemalloc.take_snapshot()​:返回当前的内存快照,包括所有的内存块和堆栈信息。
  • snapshot.filter_traces(filters)​:从快照中筛选出符合指定条件的内存块和堆栈信息。
  • snapshot.statistics([key_type])​:返回快照中的内存分配统计信息,可以按照指定的键类型进行排序。
  • snapshot.traceback([index])​:返回快照中指定索引处内存块的堆栈信息。

# 使用示例

在下面的示例中,我们首先调用 tracemalloc.start()​ 开始跟踪内存分配情况,然后执行一些代码,分配一些内存。接着,我们调用 tracemalloc.get_traced_memory()​ 获取当前内存使用量,并输出当前内存使用量和峰值内存使用量。最后,我们调用 tracemalloc.take_snapshot()​ 获取当前的内存快照,并使用 statistics()​ 方法输出内存分配统计信息。

import tracemalloc

# 开始跟踪内存分配情况
tracemalloc.start()

# 执行一些代码,分配一些内存
s = ' ' * 1000000
lst = [i for i in range(100000)]

# 获取当前内存使用量
current, peak = tracemalloc.get_traced_memory()
print(f"Current memory usage: {current / 1024 / 1024} MB")
print(f"Peak memory usage: {peak / 1024 / 1024} MB")

# 获取当前的内存快照并输出统计信息
snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics('lineno')
print("[ Top 10 ]")
for stat in top_stats[:10]:
    print(stat)

"""
Current memory usage: 4.403904914855957 MB
Peak memory usage: 4.404065132141113 MB
[ Top 10 ]
c:/Workspace/Program/CPythonTest/PyTests/tracemalloc_test.py:8: size=3532 KiB, count=99744, average=36 B
c:/Workspace/Program/CPythonTest/PyTests/tracemalloc_test.py:7: size=977 KiB, count=2, average=489 KiB
c:/Workspace/Program/CPythonTest/PyTests/tracemalloc_test.py:12: size=72 B, count=1, average=72 B
c:/Workspace/Program/CPythonTest/PyTests/tracemalloc_test.py:11: size=56 B, count=2, average=28 B
"""