2011-08-19 142 views
9

我正在運行一個包含matplotlib的django應用程序,並允許用戶指定圖形的座標軸。這可能會導致'溢出錯誤:Agg複雜度超過'Matplotlib錯誤導致內存泄漏。我怎樣才能釋放內存?

當發生高達100MB的RAM時,系統就會關閉。通常情況下,我使用fig.gcf(),plot.close()gc.collect()來釋放內存,但與錯誤相關的內存似乎不與plot對象相關聯。

有誰知道我該如何釋放內存?

謝謝。

這是一些代碼,它給了我複雜的錯誤。

import matplotlib 
matplotlib.use('Agg') 
import matplotlib.pyplot as plt 
import numpy as np  
import gc 

a = np.arange(1000000) 
b = np.random.randn(1000000) 

fig = plt.figure(num=1, dpi=100, facecolor='w', edgecolor='w') 
fig.set_size_inches(10,7) 
ax = fig.add_subplot(111) 
ax.plot(a, b) 

fig.savefig('yourdesktop/random.png') # code gives me an error here 

fig.clf() # normally I use these lines to release the memory 
plt.close() 
del a, b 
gc.collect() 

回答

9

我假設您可以運行您至少發佈一次的代碼。該問題僅在多次運行發佈代碼後纔會顯現。正確?

如果是這樣,下面的問題避免了這個問題,而沒有真正確定問題的根源。 也許這是一件壞事,但這種方式很有效:只需使用multiprocessing即可在單獨的進程中運行內存密集型代碼。您不必擔心fig.clf()plt.close()del a,bgc.collect()。當進程結束時,所有內存都將被釋放。

import matplotlib 
matplotlib.use('Agg') 
import matplotlib.pyplot as plt 
import numpy as np  

import multiprocessing as mp 

def worker(): 
    N=1000000 
    a = np.arange(N) 
    b = np.random.randn(N) 

    fig = plt.figure(num=1, dpi=100, facecolor='w', edgecolor='w') 
    fig.set_size_inches(10,7) 
    ax = fig.add_subplot(111) 
    ax.plot(a, b) 

    fig.savefig('/tmp/random.png') # code gives me an error here 

if __name__=='__main__': 
    proc=mp.Process(target=worker) 
    proc.daemon=True 
    proc.start() 
    proc.join() 

您也不必proc.join()要麼。 join將阻止主進程,直到worker完成。如果您省略了join,那麼主要過程只是繼續在後臺運行worker過程。

+0

我發佈的代碼無法在第一時間通過。它被創建用於重新創建用戶在y軸上放大得太高以適應高採樣率數據的特殊情況。如果情節看起來像沒有任何白色背景顯示的藍色洗滌,則代碼失敗。但是,您的解決方案看起來像是更好的管理內存的方式。我是一個新手,並且我不完全理解'if __name__ =='__main __':'block是怎麼回事。我會嘗試將其添加到我的代碼中。你能否指出一個解釋發生了什麼的資源?或者你可以提供一個快速解釋。謝謝。 – sequoia

+0

@sequoia:在這種情況下,您可能需要限制用戶,以免用戶請求繪製1e6點。除非您在Windows上,否則'if __name __...'塊不是必需的。我很樂意嘗試解釋任何具體的問題,但我認爲在這種情況下,所有解釋都比我可以[在這裏]更好解釋(http://docs.python.org/library/multiprocessing.html#the -process-class) – unutbu

+0

謝謝,這是一個有用的鏈接。我將使用你的實現。並採取您的建議來限制用戶請求的範圍。 – sequoia