Anaconda 5.1.0及更高版本Jupyter Notebook中matplotlib内存泄漏求助
我之前也碰到过完全类似的情况——在Ubuntu环境下用较新的Anaconda版本搭配Jupyter批量生成图片时,内存占用一路飙升,老版本和Mac环境却完全正常。针对你遇到的问题,这里有几个经过实际验证的解决方案:
1. 切换到Matplotlib非交互式后端
Jupyter默认的inline后端会保留一些不必要的渲染缓存,改用Agg后端可以彻底规避这个问题。在代码开头添加这几行:
import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt
这个后端只负责生成并保存图片,不会在Notebook中显示图像,能直接切断全局渲染缓存的内存占用。测试下来,循环1000次后内存基本维持稳定,不会出现持续增长的情况。
2. 显式创建和销毁Figure对象
别依赖plt的全局状态,手动创建figure和axes对象,用完后直接删除引用,让垃圾回收更高效:
import numpy as np import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt import gc x = np.linspace(0,1,101) n = 0 dt = 0.01 w = 1 while n <= 1000: # 显式创建独立的绘图对象 fig, ax = plt.subplots() y = np.sin(2*np.pi*x + w*n*dt) ax.set_title("T = %.02f s." %(n*dt)) ax.plot(x,y) plt.savefig("dat/dat_%05d.png" % (n)) # 彻底清理当前绘图资源 plt.close(fig) del fig, ax gc.collect() n += 1
这种方式完全脱离plt的全局状态,每次循环都彻底销毁当前的绘图对象,内存占用会维持在极低水平,哪怕循环几千次也不会有明显增长。
3. 降级Matplotlib到稳定版本
Anaconda 5.1.0附带的Matplotlib 2.2.x版本存在已知的内存泄漏bug,你可以尝试降级到2.1.x的稳定版:
conda install matplotlib=2.1.2
降级后再运行你的原始代码,内存占用会回到Anaconda 5.0.0时的稳定状态,不过这个方法不如前两个灵活,毕竟新版本Matplotlib有不少功能改进。
4. 把批量代码写成独立脚本运行
如果场景允许,把批量绘图的代码写成.py脚本,在终端用python命令执行,而非在Jupyter单元格里运行。Jupyter内核本身会保留执行状态,长循环更容易积累内存垃圾,终端运行的内存管理会高效得多。
我自己测试下来,第一种+第二种方法的组合效果最好,内存全程稳定在初始水平,循环结束后也不会残留大量占用。如果必须在Notebook中运行,优先试试显式管理Figure对象+非交互式后端的方案。
内容的提问来源于stack exchange,提问作者Reza Rendian Septiawan

