编程学习网 > 编程语言 > Python > python面试题:内存泄露是什么?如何避免?
2025
06-04

python面试题:内存泄露是什么?如何避免?


内存泄露这个事,第一次让我警觉是在一个线上服务隔三差五就崩掉的深夜。我排查了半天,最后 top 命令一看,那个 Python 服务的内存直接飙上天了。

你说奇怪吧,明明没有什么特别重的运算任务,逻辑也挺简单的。一开始我怀疑是哪里忘了释放资源,结果一查,还真是个小细节惹的祸:一个死循环里不断 append 对象到列表,结果这个列表压根没清空过。那一刻我才真正体会到,什么叫“内存慢性中毒”。

内存泄露到底是个啥?

先甩个定义:内存泄露(Memory Leak)指的是程序在申请内存之后忘记释放,导致这部分内存长期占用、无法回收。

虽然 Python 有垃圾回收机制(GC),表面上听起来“自动管理内存”,但这不代表你能高枕无忧。Python 的 GC 机制主要基于引用计数,当一个对象的引用计数为 0 时,内存才会被回收。

而如果你写了个引用环,或者你用某种方式偷偷藏了一堆对象的引用,那这些对象就永远活着,GC 根本管不着。

比如下面这个例子,就挺有代表性:

这个脚本你让它跑,内存就一路疯涨。为啥?因为 leaks 一直在保存着对象引用,导致 GC 永远不会回收这些 Leaky 实例。

Python 里怎么会“漏”?

说实话,Python 里的内存泄露不太像 C/C++ 那种“我申请了 malloc() 忘了 free()”,更多时候是逻辑没理清,导致对象一直被引用着。

常见场景有哪些?

  1. 1. 全局变量误用
    全局变量没控制好,对象永远在那儿挂着不释放。
  2. 2. 闭包引用
    闭包引用外部变量,结果引用链断不了,比如下面这样:

  1. 只要你保存了 inner,那 local_data 也一直活着。
  2. 3. 缓存没清理
    LRU 缓存结果,忘记加 size 限制。尤其是 functools.lru_cache,默认是无限缓存。
  3. 4. 循环引用
    A 引用 B,B 又引用 A,如果其中有 __del__ 方法,GC 甚至都懒得动它们。
  4. 5. 事件监听器没移除
    比如你写 GUI 或者一些 WebSocket 的订阅者模式,监听器一直在监听,但你早就不需要了。

怎么发现内存泄露?

说到这里,我觉得最实用的技巧不是“改代码”而是“先定位”。很多时候你得先知道是哪段逻辑在偷偷占内存,否则就是盲人摸象。

我比较常用的方法有这些:

1. 内存快照

tracemalloc 是 Python 自带的模块,挺好用的:

这能帮你快速找出内存占用多的地方。

2. objgraph

这是我最喜欢的图形分析工具之一,可以画出对象的引用链:

你就能看见这个 some_obj 是被谁引用着,像一张蛛网一样。

3. memory_profiler

这个库可以帮你按函数粒度监控内存变化:

跑完之后,它会告诉你每行代码的内存消耗。

怎么避免呢?

1. 掌握引用链

养成习惯,每写一个新类,脑子里最好有张“谁引用谁”的图,特别是数据结构里互相引用的场景。

2. 少用全局变量

真的,有时候一个不注意就搞出一个“全局大粪池”,啥都往里扔,谁也不敢清。

3. 控制缓存大小

比如 functools.lru_cache(maxsize=128),千万别忘了设 maxsize

4. 监听器记得清除

很多人用 PyQt 写界面或者用某种 pub-sub 模式的时候,监听器绑得欢,解绑的时候就偷懒了。结果一个窗口对象关了半天内存还是飙着。

5. 监控系统资源

用 psutil 定时去测当前 Python 进程的内存使用情况,一旦发现异常增长,立马出手干预。

我的看法

我觉得,内存泄露在 Python 项目里虽然没那么频繁,但一旦出现就特别隐蔽,属于“你以为你写得没问题,其实早就炸了”。尤其是做服务端开发,程序长时间运行,一点点泄露堆积到几天后,就能把整个服务拖死。真是防不胜防。

所以我建议,不管你用什么框架,Flask、Django 也好,FastAPI 也罢,长期运行的服务最好加上定期内存监控,配合 tracemallocobjgraph 这种工具,一旦发现内存不对劲,别犹豫,开干。

还有一个我觉得挺重要的点就是“代码审查时不光看功能,也要顺便看看资源使用”。很多时候内存泄露就是你自己挖的坑,埋得太深,连你自己都忘了。

就像我上面那个“死循环往列表加对象”问题,看起来就是个小测试代码,谁会想到能把服务器撑爆?

现在我项目里专门有个“内存告警系统”,一旦进程内存超过阈值,立刻打日志、发邮件、自动拉内存快照。别等出事才开始查。

体验地址就没啥了,内存泄露这个事,得靠你手上的 Python 自己管起来。要是你现在就怀疑项目有问题,立刻试试上面的 tracemalloc 或 objgraph,可能你会发现惊喜(或者惊吓)。

以上就是“python面试题:内存泄露是什么?如何避免?的详细内容,想要了解更多Python教程欢迎持续关注编程学习网。



扫码二维码 获取免费视频学习资料

Python编程学习

查 看2022高级编程视频教程免费获取