为什么 del 之后内存不立即释放?
Python 的内存回收依赖引用计数 + 垃圾收集器(gc),del 只是减少引用计数,并不保证立刻归还内存给操作系统。尤其当对象被循环引用、或位于大容器中未被完全清理时,gc.collect() 也未必能马上触发释放。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 用
sys.getsizeof()查对象本身内存(不含子对象),配合obj.__dict__或vars()检查大字段;不要只看del是否执行成功 - 对已知生命周期的大型数据结构(如临时 DataFrame、缓存字典),显式调用
gc.collect()后再检查psutil.Process().memory_info().rss - 避免在长生命周期对象(如类实例、模块级变量)中持有短命大数据的引用——这是最隐蔽的内存泄漏源
如何安全地复用 list 和 dict 而不反复分配?
频繁创建/销毁中等大小容器(比如每次请求生成几千项的 list)会带来显著分配开销和内存碎片。工程上更优的做法是「池化」或「预分配+清空」。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 用
list.clear()替代重新赋值my_list = []:前者复用底层数组内存,后者触发新分配 - 对固定上限场景(如日志缓冲区),初始化时用
[None] * N预占空间,再用索引写入 +del list[:used_len]截断 -
dict不支持.clear()复用底层哈希表结构(CPython 3.12+ 开始优化,但旧版本仍会逐步扩容缩容),可考虑改用collections.OrderedDict或第三方simplejson的池化工具
哪些 __slots__ 场景真正节省内存?
__slots__ 对单个实例节省有限(约 48–96 字节),但当创建数十万以上实例(如 ORM 模型、解析后的 AST 节点)时,累积效果明显——关键是它禁用 __dict__,阻止动态属性写入。