【问题标题】:Spyder does not release memory for matplotlib plotsSpyder 不会为 matplotlib 绘图释放内存
【发布时间】:2019-12-15 23:31:45
【问题描述】:

我使用 Spyder 3.3.6,在 IPyhton 7.7.0 cosole 上使用 Pyhton 3.7.3。

出于不同的原因,Spyder 一直是我的首选 IDE,但现在我决定完全放弃它,只使用命令提示符。

原因是我在使用 matplotlib 时看到了由 Spyder 引起的严重内存泄漏。

内存线性增加,直到我所有的 128 GB 内存被消耗到我的 Ubuntu 机器完全停止并且我不得不硬重置它的程度。我过去在 matplotlib 和我找到的解决方案中遇到过这个问题,比如使用

plt.close('all')plt.close(fig)gc.collect()

在一定程度上有所帮助,但这次没有奏效(我应该补充一点,我正在使用 MNE 库来绘制一长串 EEG 原始文件,因此我无法尝试针对此类 matplotlib 内存问题存在的所有可能解决方案)。

但是当我在命令提示符下同时使用 python 和 ipython 运行相同的代码时,一个简单的

plt.close(fig) 

解决了这个问题,并且在整个运行过程中内存保持在几 GB 左右。因此,唯一合乎逻辑的结论是 Spyder 不知何故弄乱了内存管理。

所以,我写了这个问题,以防有人知道这个问题的解决方案,或者如果不知道,其他使用 Spyder 并且可能浪费时间试图找到 python 解决方案的人会知道问题出在 Spyder,而不是 python。

【问题讨论】:

  • (这里是 Spyder 维护者) 我怀疑这是 Spyder 的问题,因为我们使用的执行模型与 Jupyter notebook 基本相同(有一些小的添加)。您能否验证此问题是否也出现在笔记本中?
  • 我猜问题出在使用 Spyder 使用的 qt IPython 控制台。过去我也遇到过几个问题,我目前正在做的是让 Spyder 通过外部控制台执行代码(在外部系统终端中的首选项/运行/执行)。我还停用了 matplotlib 支持(首选项/IPython/图形/激活 matplotlib 支持);这并不意味着不支持 matplotlib,而是 Spyder 不会尝试设置任何后端等。总的来说,这允许使用 Spyder,但仍然像运行脚本一样运行代码。
  • @ImportanceOfBeingErnest 我进行了一些测试,结果如下。在所有情况下,我将 MNE 图分配给一个名为“fig”的对象,然后使用 plt.close(fig)。 1. 我在同一个环境中安装了 Jupyter。运行其中的代码,遇到同样的问题。 2. 在 Spyder 中,未选中的首选项/IPython 控制台/图形/激活支持,重新启动 spyder,运行代码,遇到同样的问题。 3.在Spyder中,保持之前的设置,选择'Execute in external system terminal',重启Spyder,运行代码,这次问题解决了。

标签: python-3.x matplotlib memory-leaks ipython spyder


【解决方案1】:

对我来说,使用gc.collect 解决了这个问题。 我正在使用:Spyder 3.3.6、Python 3.7.6、Ipython 7.11.1。

最小的工作/崩溃示例

下面的代码不会崩溃,但可以通过注释/取消注释指示的两行来修改以导致内存泄漏。

import numpy as np
import matplotlib.pylab as plt
import os
import psutil
import gc
process = psutil.Process(os.getpid())
def str_mem_usage():
    mu = process.memory_info().rss / 1024**2
    return 'Memory usage: {:.2f} MB'.format(mu)
    
arrs = []
for ii in range(10):
    print('it', ii, '\t', str_mem_usage())
    n = 10000
    arr = np.random.rand(n**2).reshape(n, n)
    #arrs += [arr]  # activate to cause memory leak, obviously
    
    plt.ioff()
    fig, ax = plt.subplots(1, 1)
    ax.imshow(arr)
    #plt.savefig('tmp.pdf')  # irrelevant for memory leak
    plt.close(fig)
    plt.ion()
    
    gc.collect()  # deactivate to cause memory leak

在 Spyder 中执行或从 Anaconda 发行版调用 Python 或 iPython 时,此行为是相同的。

输出(无内存泄漏)

it 0     Memory usage: 147.35 MB
it 1     Memory usage: 1682.64 MB
it 2     Memory usage: 1682.98 MB
it 3     Memory usage: 1682.99 MB
it 4     Memory usage: 1682.99 MB
it 5     Memory usage: 1682.99 MB
it 6     Memory usage: 1678.63 MB
it 7     Memory usage: 1644.47 MB
it 8     Memory usage: 1633.58 MB
it 9     Memory usage: 1633.56 MB

输出(内存泄漏)

it 0     Memory usage: 108.89 MB
it 1     Memory usage: 1635.26 MB
it 2     Memory usage: 2393.71 MB
it 3     Memory usage: 3156.51 MB
it 4     Memory usage: 3919.34 MB
it 5     Memory usage: 4681.07 MB
it 6     Memory usage: 5428.71 MB
...
MemoryError: Unable to allocate 763. MiB for an array with shape (100000000,) and data type float64

也许这个答案可以帮助一些人重现/解决这个 Matplotlib 内存泄漏问题。这可能是我第 5 次遇到它。

【讨论】:

    猜你喜欢
    • 2016-02-24
    • 1970-01-01
    • 2018-04-06
    • 1970-01-01
    • 2022-01-24
    • 2014-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多