如何完全清除所有Matplotlib图的记忆

AKK*_*KKO 19 python memory matplotlib

我有数据分析模块,其中包含多次调用Matplotlib pyplot API的函数,每次运行时最多可生成30个数字.这些数字在生成后会立即写入磁盘,因此我需要从内存中清除它们.目前,在我的每个功能结束时,我都这样做

import matplotlib.pyplot as plt

plt.clf()
Run Code Online (Sandbox Code Playgroud)

但是我不太确定这个陈述是否能真正清除记忆.我特别担心,因为我看到每次运行模块进行调试时,我的可用内存空间不断减少.任何人都可以告诉我,在我将这些图写入磁盘后,每次我需要做些什么才能真正清除我的记忆?

谢谢.

小智 35

经过一周的试验,我得到了我的解决方案!希望它可以帮助你。我的演示已附上。

import matplotlib.pyplot as plt
import numpy as np

A = np.arange(1,5)
B = A**2

cnt=0
while(1):  
    cnt = cnt+1
    print("########### test %d ###########" % cnt)

    # here is the trick: 
    # set the figure a 'num' to prevent from re-malloc of a figure in the next loop 
    # and set "clear=True" to make the figure clear
    # I never use plt.close() to kill the figure, because I found it doesn't work.
    # Only one figure is allocated, which can be self-released when the program quits.
    # Before: 6000 times calling of plt.figure() ~ about 1.6GB of memory leak
    # Now: the memory keeps in a stable level
    fig = plt.figure(num=1, clear=True)
    ax = fig.add_subplot()

    # alternatively use an other function in one line
    # fig, ax = plt.subplots(num=1,clear=True)

    ax.plot(A,B)
    ax.plot(B,A)

    # Here add the functions you need 
    # plt.show()
    fig.savefig('%d.png' % cnt)
Run Code Online (Sandbox Code Playgroud)

  • 可以作证,就像魅力一样。请注意,如果将 plt.close(f) 与上述解决方案结合使用,内存泄漏仍然会发生。 (4认同)

Lui*_* DG 6

尤其是当您运行多个进程或线程时,最好定义图形变量并直接使用它:

from matplotlib import pyplot as plt

f = plt.figure()
f.clear()
plt.close(f)
Run Code Online (Sandbox Code Playgroud)

无论如何,您必须结合使用plt.clear()和plt.close()


Pri*_*hil 5

我有数据分析模块,其中包含多个调用 Matplotlib pyplot API 的函数

您可以编辑调用 matplotlib 的函数吗?我遇到了同样的问题,我尝试了以下命令,但没有奏效。

plt.close(fig)
fig.clf()
gc.collect()
%reset_selective -f fig
Run Code Online (Sandbox Code Playgroud)

然后一个技巧对我有用,而不是每次都创建一个新图形,我将相同的 fig 对象传递给函数,这解决了我的问题。

例如使用,

fig = plt.figure()
for i in range(100):
    plt.plot(x,y)
Run Code Online (Sandbox Code Playgroud)

代替,

for i in range(100):
    fig = plt.figure()
    plt.plot(x,y)
Run Code Online (Sandbox Code Playgroud)


D A*_*ams 5

这更像是一个测试套件,而不是问题的答案。在这里,我展示了截至 2021 年 12 月,没有提供的解决方案能够真正清除内存。

我们需要以下库:

import os
import psutil 
import numpy
import matplotlib
import matplotlib.pyplot
Run Code Online (Sandbox Code Playgroud)

我创建了一个应该清除所有 matplotlib 内存的函数:

def MatplotlibClearMemory():
    #usedbackend = matplotlib.get_backend()
    #matplotlib.use('Cairo')
    allfignums = matplotlib.pyplot.get_fignums()
    for i in allfignums:
        fig = matplotlib.pyplot.figure(i)
        fig.clear()
        matplotlib.pyplot.close( fig )
    #matplotlib.use(usedbackend) 
Run Code Online (Sandbox Code Playgroud)

我编写了一个脚本,创建 100 个图形,然后尝试将它们全部从内存中删除:

#Use TkAgg backend because it works better for some reason:
matplotlib.use('TkAgg')

#Create fake data for our figures:
x = numpy.arange(1000)

#Get system process information for printing memory usage:
process = psutil.Process(os.getpid())

#Check memory usage before we create figures:
print('BeforeFigures: ', process.memory_info().rss)  # in bytes

#Make 100 figures, and check memory usage:
for n in range(100):
    matplotlib.pyplot.figure()
    matplotlib.pyplot.plot(x, x)
print('AfterFigures:  ', process.memory_info().rss)  # in bytes

#Clear the all the figures and check memory usage:
MatplotlibClearMemory( )
print('AfterDeletion: ', process.memory_info().rss)  # in bytes
Run Code Online (Sandbox Code Playgroud)

输出剩余内存:

>>> BeforeFigures: 76083200
>>> AfterFigures:  556888064
>>> AfterDeletion: 335499264
Run Code Online (Sandbox Code Playgroud)

不到一半的分配内存被清除(如果使用标准后端则更少)。此堆栈溢出页面上唯一可行的解​​决方案是避免同时将多个数字放入内存中。