1. Python 内存管理概述
Python 使用私有堆管理内存,核心机制包括引用计数和垃圾回收。对象分配由 PyObject 管理,小对象使用 pymalloc 分配器。
2. 引用计数
每个对象维护ob_refcnt。引用增加:
python
复制
下载
a = [] b = a # 引用计数 +1
引用减少:
python
复制
下载
del b
引用计数为 0 时立即释放。
3. 循环引用问题
python
复制
下载
class Node: def __init__(self): self.next = None a = Node() b = Node() a.next = b b.next = a del a, b
此时引用计数不为 0,需要 GC 处理。
4. 垃圾回收
Python GC 分三代:0、1、2。新对象在第 0 代,经历回收后晋升。可通过gc模块控制:
python
复制
下载
import gc gc.collect() gc.get_threshold() gc.set_threshold(700, 10, 10)
5. 查看内存使用
python
复制
下载
import sys a = [1, 2, 3] print(sys.getsizeof(a))
使用psutil查看进程内存:
python
复制
下载
import psutil, os process = psutil.Process(os.getpid()) print(process.memory_info().rss / 1024 / 1024, "MB")
6. tracemalloc 排查内存泄漏
python
复制
下载
import tracemalloc tracemalloc.start() # 执行可疑代码 snapshot = tracemalloc.take_snapshot() top_stats = snapshot.statistics("lineno") for stat in top_stats[:10]: print(stat)7. 常见内存泄漏场景
全局列表不断追加。
闭包引用大对象。
缓存未设置过期。
循环引用 +
__del__。C 扩展未释放。
8. 优化技巧
使用生成器代替列表:
python
复制
下载
def read_lines(path): with open(path) as f: for line in f: yield line
使用
__slots__减少对象内存:
python
复制
下载
class Point: __slots__ = ("x", "y") def __init__(self, x, y): self.x = x self.y = y使用
array、numpy存储数值。及时释放大对象:
del+gc.collect()。使用内存池或对象复用。
9. 性能分析
cProfile:
bash
复制
下载
python -m cProfile -s cumtime script.py
line_profiler:
bash
复制
下载
kernprof -l -v script.py
10. 实战案例
某服务运行 24 小时后内存从 200MB 涨到 2GB。使用 tracemalloc 定位到全局字典缓存未清理。改为 LRU 缓存后稳定在 300MB。
11. 总结
Python 内存管理看似自动,实则需要注意循环引用、缓存和全局对象。掌握 tracemalloc、gc 和 cProfile,可以快速定位并解决内存与性能问题。