0Pricing
Python Academy · 课时

使用 tracemalloc 进行内存分析

使用 tracemalloc 跟踪内存分配并查找内存泄漏。

使用 tracemalloc 进行内存分析 是 CoddyKit 上的免费 Python Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Python Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Python Academy 课程共包含 4 节课。

什么是 tracemalloc?

tracemalloc 是一个标准库模块,可按文件和行号跟踪 Python 的内存分配。

import tracemalloc

tracemalloc.start()

x = [i for i in range(100_000)]

current, peak = tracemalloc.get_traced_memory()
tracemalloc.stop()

print(f"Current: {current/1024:.1f} KB")
print(f"Peak:    {peak/1024:.1f} KB")

获取快照

快照会捕获某个时间点的所有当前内存分配。比较两个快照,可以找出这两个时间点之间分配的内存。

import tracemalloc

tracemalloc.start()

snap1 = tracemalloc.take_snapshot()

data = [{"key": str(i)} for i in range(10_000)]

snap2 = tracemalloc.take_snapshot()

stats = snap2.compare_to(snap1, "lineno")
for stat in stats[:5]:
    print(stat)

筛选快照

将统计信息筛选为仅显示应用程序代码,并排除标准库。

import tracemalloc

tracemalloc.start()
leak_function()
snap = tracemalloc.take_snapshot()

filters = [tracemalloc.Filter(True, "*/myapp/*")]
stats = snap.filter_traces(filters).statistics("lineno")
for stat in stats[:10]:
    print(stat)

主要内存分配位置

使用 snapshot.statistics("lineno") 或 "traceback",按代码行或完整回溯查看占用内存最多的位置。

import tracemalloc

tracemalloc.start(nframe=10)   # track 10 frames deep

big_list = [i**2 for i in range(500_000)]

snap = tracemalloc.take_snapshot()
for stat in snap.statistics("traceback")[:3]:
    print(stat)
    for line in stat.traceback.format():
        print("  ", line)

查找内存泄漏

在疑似发生泄漏的位置前后分别获取快照并进行比较。如果两个快照之间的统计数据不断增长,就表明存在内存泄漏。

import tracemalloc

tracemalloc.start()
snap_before = tracemalloc.take_snapshot()

for _ in range(100):
    suspected_leaky_function()

snap_after = tracemalloc.take_snapshot()
diff = snap_after.compare_to(snap_before, "lineno")
for stat in diff[:5]:
    print(stat)

get_traced_memory()

tracemalloc.get_traced_memory() 返回以字节为单位的 (current, peak),适用于轻量级的前后对比检查。

import tracemalloc

tracemalloc.start()
before, _ = tracemalloc.get_traced_memory()

do_something()

after, peak = tracemalloc.get_traced_memory()
tracemalloc.stop()

print(f"Delta: {(after-before)/1024:.1f} KB, Peak: {peak/1024:.1f} KB")

memory_profiler

memory_profiler 提供逐行内存使用情况,类似于用于 CPU 分析的 line_profiler。

# pip install memory_profiler
from memory_profiler import profile

@profile
def build_data():
    data = [i**2 for i in range(100_000)]
    filtered = [x for x in data if x % 2 == 0]
    return filtered

build_data()
# python -m memory_profiler script.py

memray

memray(由 Bloomberg 开发)是一款快速的 Python 内存分析器,可输出火焰图。

# pip install memray
# python -m memray run script.py
# python -m memray flamegraph memray-script.py.bin

# Generates an interactive HTML flamegraph
# showing allocations by call stack

降低内存使用量

常见方法包括:使用生成器代替列表、使用 __slots__、使用 array 模块存储数值数据、使用 numpy 数组,以及避免让闭包长期持有大型对象。

# Instead of:
data = [process(x) for x in huge_list]   # all in memory

# Use a generator:
def gen_data(lst):
    for x in lst:
        yield process(x)

for item in gen_data(huge_list):
    consume(item)   # one at a time

sys.getsizeof()

sys.getsizeof(obj) 返回对象本身使用的内存量(以字节为单位;这是浅层大小,不包括被引用的对象)。

import sys

print(sys.getsizeof([]))          # 56
print(sys.getsizeof([1,2,3]))     # 88
print(sys.getsizeof("hello"))     # 54
print(sys.getsizeof({}))          # 64

# For deep size, use recursive measurement:
def deep_size(obj):
    return sys.getsizeof(obj) + sum(
        sys.getsizeof(v) for v in vars(obj).values()
        if hasattr(obj, "__dict__")
    )

在生产环境中进行分析

在生产环境中使用 tracemalloc 时,请限制 nframes,以尽量降低开销。将快照保存到文件中,以便离线分析。

import tracemalloc, pickle

tracemalloc.start(nframe=5)   # low overhead

# ... serve some requests ...

snap = tracemalloc.take_snapshot()
with open("snap.pkl","wb") as f:
    pickle.dump(snap, f)
# Analyse later offline

快速检查

tracemalloc.get_traced_memory() 返回的两个值分别表示什么?

回顾

使用 tracemalloc.start() 和快照查找内存泄漏。使用 compare_to() 比较快照。使用 memory_profiler 查看逐行内存使用情况,使用 memray 生成火焰图。使用生成器、__slots__ 和 NumPy 数组来减少内存使用量。

常见问题解答

「使用 tracemalloc 进行内存分析」课时是免费的吗?

是的 — 「使用 tracemalloc 进行内存分析」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Python Academy 课程的其余内容,请升级到 CoddyKit PRO。 Python Academy 课程共包含 4 节课。

「使用 tracemalloc 进行内存分析」这节课中我会学到什么?

使用 tracemalloc 跟踪内存分配并查找内存泄漏。 你通过在浏览器中直接运行的动手代码来练习 Python Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Python Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Python Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「使用 tracemalloc 进行内存分析」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Python Academy 课中编写并运行代码吗?

能。每节 Python Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. CPython 引用计数
  2. 垃圾回收器与循环引用
  3. 使用 cProfile 和 line_profiler 进行性能分析
  4. 使用 tracemalloc 进行内存分析
← 返回 Python Academy