Jupyter Notebook内存无法释放求助:实验复现及现象描述
Jupyter Notebook内存无法释放?这几个原因和解决办法帮你搞定
你描述的这个情况我之前也碰到过——创建大NumPy数组后,用%reset_selective释放内存,top里看内存占用纹丝不动,重复操作还会持续涨内存。先复盘下你的实验过程:
- 创建800MB左右的数组:
var_tmp = np.random.randn(10000,10000) - 用
top确认内存占用增加800MB - 执行
%reset_selective -f var_tmp后,内存无变化,重复操作内存持续增长
为啥会这样?
核心原因其实和Python的内存管理逻辑、Jupyter的运行特性有关:
- 隐性引用没清干净:Jupyter会自动把最后一次输出存在
_变量里,如果你创建数组后直接运行了变量名(比如输入var_tmp然后回车),_就会指向这个数组,哪怕你用%reset_selective删了var_tmp,_还拿着引用,垃圾回收器没法回收。 - Python不会立刻归还内存给系统:就算垃圾回收器回收了数组对象,Python会把释放的内存留作“备用池”,供后续分配使用,不会立刻还给操作系统,所以
top里看到的RSS(常驻内存)不会马上下降。 %reset_selective的局限性:这个命令只是移除了指定变量名的引用,但如果数组还被其他对象引用(比如函数闭包、全局变量列表里的残留项),就没法真正触发回收。
怎么解决?
给你几个实用的方案,按优先级排序:
1. 手动触发垃圾回收+清隐性引用
先把变量置为None,再强制垃圾回收,同时清空Jupyter的输出缓存:
var_tmp = None # 主动断开引用 import gc gc.collect() # 强制触发垃圾回收 %reset -f _ # 清空自动保存的最后输出变量
执行完后再用top或者psutil检查,内存应该会有变化(如果没有被其他引用占着的话)。
2. 用psutil精准查看内存
top显示的是进程的总内存占用,没法区分Python内部已回收但未归还的内存。可以用psutil看更细的指标:
import psutil proc = psutil.Process() print(f"实际使用内存: {proc.memory_info().rss / 1024/1024:.2f} MB") print(f"Python已分配但未使用的内存: {(proc.memory_info().vms - proc.memory_info().rss)/1024/1024:.2f} MB")
如果rss下降了,说明内存已经被回收,只是Python没还给系统而已,后续创建新对象会优先用这些闲置内存。
3. 重启内核
如果内存已经爆得厉害,或者上面的方法不管用,最直接的就是重启Jupyter内核——这会彻底清空所有内存,但记得先保存你的代码和数据。
4. 用内存分析工具定位泄漏
如果经常碰到内存问题,可以用memory_profiler追踪每一行代码的内存变化,找出隐性引用的来源:
!pip install memory_profiler from memory_profiler import profile @profile def test_memory(): var_tmp = np.random.randn(10000,10000) # 这里加你的释放操作 %reset_selective -f var_tmp
运行后会显示每一行的内存变化,帮你找到哪里没释放干净。
小提醒:如果是长期运行的Jupyter任务,尽量避免反复创建大数组后只删变量名,最好在不用的时候主动置为
None并触发垃圾回收,防止内存积累。
内容的提问来源于stack exchange,提问作者user40780
相关产品推荐
相关产品推荐

