2015-09-29 20 views
6

私はそれをディスクに異なるパラメータ(QK)、プロット結果を格納するために多くのシミュレーションを行いPythonスクリプトを持っています。はnumpyのとmatplotlibのガベージコレクション

パラメータの各セット(Q,K)は、データ100xMBのデータを必要とするデータ200x200x80データポイントの3Dボリュメトリックグリッドを生成します。次に、この体積測定グリッドの一部分を層毎にプロットし、約60枚の画像を生成する。

問題は、このプロセス中にPythonが明らかにメモリを解放しないことです。私はメモリリークがどこにあるのか、あるいはPythonがどのオブジェクトが割り当て解除されるかを決定するルールを管理しているかどうかはわかりません。私はまた、メモリがnumpy配列で失われているか、matplotlibのFigureオブジェクトで失われているかどうかはわかりません。

  1. はPythonでオブジェクトを分析するための簡単な方法があるメモリに存続している自動的に解放されましたか?
  2. 特定のループサイクルまたは特定の関数呼び出しで作成されたすべての配列と図形オブジェクトをPythonで割り当てを解除する方法がありますか?

    import numpy as np 
    import matplotlib.pyplot as plt 
    import ProbeParticle as PP # this is my C++/Python simulation library, take it as blackbox 
    
    def relaxedScan3D(xTips, yTips, zTips): 
        ntips = len(zTips); 
        print " zTips : ",zTips 
        rTips = np.zeros((ntips,3)) # is this array deallocated when exiting the function? 
        rs = np.zeros((ntips,3)) # and this? 
        fs = np.zeros((ntips,3)) # and this? 
        rTips[:,0] = 1.0 
        rTips[:,1] = 1.0 
        rTips[:,2] = zTips 
        fzs = np.zeros((len(zTips), len(yTips), len(xTips))); # and this? 
        for ix,x in enumerate(xTips ): 
         print "relax ix:", ix 
         rTips[:,0] = x 
         for iy,y in enumerate(yTips ): 
          rTips[:,1] = y 
          itrav = PP.relaxTipStroke(rTips, rs, fs)/float(len(zTips)) 
          fzs[:,iy,ix] = fs[:,2].copy() 
        return fzs 
    
    
    def plotImages(prefix, F, slices): 
        for ii,i in enumerate(slices): 
         print " plotting ", i 
         plt.figure(figsize=(10,10)) # Is this figure deallocated when exiting the function ? 
         plt.imshow(F[i], origin='image', interpolation=PP.params['imageInterpolation'], cmap=PP.params['colorscale'], extent=extent) 
         z = zTips[i] - PP.params['moleculeShift' ][2] 
         plt.colorbar(); 
         plt.xlabel(r' Tip_x $\AA$') 
         plt.ylabel(r' Tip_y $\AA$') 
         plt.title(r"Tip_z = %2.2f $\AA$" %z ) 
         plt.savefig(prefix+'_%3.3i.png' %i, bbox_inches='tight') 
    
    Ks = [ 0.125, 0.25, 0.5, 1.0 ] 
    Qs = [ -0.4, -0.3, -0.2, -0.1, 0.0, +0.1, +0.2, +0.3, +0.4 ] 
    
    for iq,Q in enumerate(Qs): 
        FF = FFLJ + FFel * Q 
        PP.setFF_Pointer(FF) 
        for ik,K in enumerate(Ks): 
         dirname = "Q%1.2fK%1.2f" %(Q,K) 
         os.makedirs(dirname) 
         PP.setTip(kSpring = np.array((K,K,0.0))/-PP.eVA_Nm) 
         fzs = relaxedScan3D(xTips, yTips, zTips) # is memory of "fzs" recycled or does it consume more memory each cycle of the loop ? 
         PP.saveXSF(dirname+'/OutFz.xsf', headScan, lvecScan, fzs) 
         dfs = PP.Fz2df(fzs, dz = dz, k0 = PP.params['kCantilever'], f0=PP.params['f0Cantilever'], n=int(PP.params['Amplitude']/dz)) # is memory of "dfs" recycled? 
         plotImages(dirname+"/df", dfs, slices = range(0, len(dfs))) 
    

コードの関連部分は、ここで(ただし、それはそれはあまりにも複雑であるため、...​​C++/Pythonインタフェースを含むシミュレーションコードのより大きな部分が省略されて実行されません)です

+3

問題は、すべての図形を保持して開いていることです。 'pyplot'のステートマシンインターフェースを使うつもりなら、毎回明示的に数字を閉じる必要があります。さもなければ、 'plt.show'を呼び出すときに表示されるように、それらは保持されます。迅速な修正として、 'plt.savefig'の後に' plt.close() 'を呼び出してください。 –

+0

Ahoj Prokope、matplotlibを利用する方法については別の方法を試してみてください>>> ** ['Matplotlibを使った対話型アプリケーション; Benjamin V. Root、(2015) '] ** – user3666197

+0

前菜として、埋め込まれたMVC - ** live-'matplotlib-GUIサンプル>>> http://stackoverflow.com/a/25769600/3666197 ** – user3666197

答えて

7

はあなたの姿を再利用してください:

plt.figure(0, figsize=(10, 10)) 
plt.clf() #clears figure 

または保存した後、あなたの姿を閉じる:

... 
plt.savefig(...) 
plt.close() 
+1

aha、ありがとう、 'plt.close()'ではもうメモリリークがないようです。それでも、規則が何であるか、そしてこの漏れを分析する方法を明確にしておくことは良いことです。 –

+0

pyplotを使用すると、リークはありません。plt.figureは、毎回新しいフィギュアを提供し、古いものは 'plt.figure(n)'を呼び出すことで利用可能になります.nはフィギュアの番号です。 – tillsten

関連する問題