很多人觉得 Python 是带垃圾回收机制的嘛,那应该不会内存泄漏吧?但其实情况没那么简单。Python 的垃圾回收确实能帮我们回收大部分不用的对象,可一旦遇到某些特殊场景,它也可能“收不回去”,久而久之就会表现成内存泄漏。
最常见的就是循环引用。比如两个对象互相引用,即使它们本身已经不再需要了,引用计数也没归零,GC 就没法释放它们。虽然 Python 的垃圾回收器能处理一部分循环引用,但如果里面还混着一些特殊对象(比如文件描述符、socket 这类带外部资源的),就可能被遗漏。
再一个就是全局变量或者缓存。写代码的时候一不小心把数据放在全局变量里没清理,程序长时间跑下来内存就会越占越多。尤其是写服务的时候,典型的就是“缓存忘记淘汰”。
另外,C 扩展模块也是重灾区。如果底层扩展没有正确释放内存,就算 Python 层面上对象没了,底层内存依旧占着。这种问题在用第三方库时比较常见。
下面这个例子就是一个典型的循环引用问题:
按理说 a 和 b 都删了,内存应该被释放,但因为它们互相引用,引用计数没清零,所以内存会卡在那里。GC 虽然会尝试处理,但如果里面牵扯到外部资源,就可能清不干净。
怎么排查内存泄漏
- 用 gc 模块:gc.collect() 可以手动触发垃圾回收,gc.garbage 可以看到没被回收的对象。
- 用 objgraph:能画出对象引用关系,很直观地看到哪些东西还挂着。
- 用 tracemalloc:Python 内置的内存分配跟踪工具,可以帮你找到哪里分配了多少内存。
示例:

运行完你就能看到是哪个代码行占了最多内存,非常适合排查。
避免内存泄漏的小技巧
- 用完的变量及时 del,尤其是大对象。
- 对缓存要有过期策略,别无限增长。
- 少用全局变量,能传参就传参。
- 循环引用要小心,必要时用 weakref 弱引用来避免。
- 如果怀疑是第三方库的锅,可以尝试升级版本,或者换个库。
Python 并不是完全免疫内存泄漏的,垃圾回收只是帮你省心,但不是万能。写服务的时候最好还是定期监控内存占用,发现异常早点查,不然真等到内存爆了,排查起来会很痛苦。
以上就是“python会不会出现内存泄漏?”的详细内容,想要了解更多Python教程欢迎持续关注编程学习网。扫码二维码 获取免费视频学习资料
- 本文固定链接: http://www.phpxs.com/post/13551/
- 转载请注明:转载必须在正文中标注并保留原文链接
- 扫码: 扫上方二维码获取免费视频资料
查 看2022高级编程视频教程免费获取