Ich habe ein Python-Skript, das viele Simulationen für verschiedene Parameter (Q
, K
), Plots Ergebnisse und speichert sie auf der Festplatte der Fall ist.Numpy und matplotlib Garbage Collection
Jeder Parametersatz (Q,K
) erzeugt ein dreidimensionales Volumenraster mit 200x200x80 Datenpunkten, für das ca. 100 MB Daten benötigt werden. Ein Teil dieses volumetrischen Rasters wird dann Schicht für Schicht aufgetragen, wobei ~ 60 Bilder erzeugt werden.
Das Problem ist, dass Python offensichtlich nicht Speicher während dieses Prozesses freigibt. Ich bin mir nicht sicher, wo der Speicherleck ist, oder was die Regeln regeln, wie Python entscheidet, welche Objekte freigegeben werden. Ich bin auch nicht sicher, ob der Speicher in numpy
Arrays oder in matplotlib
Abbildung Objekte verloren ist.
- Gibt es eine einfache Art und Weise, die in Python-Objekte zu analysieren im Speicher fortbestehen und die automatisch freigegeben wurden?
- Gibt es eine Möglichkeit, Python zu zwingen, alle Arrays und Abbildung Objekte zu entziehen, die in bestimmten Schleife Zyklus oder insbesondere Funktionsaufruf erstellt wurden?
Der relevante Teil des Codes ist hier (wie auch immer, wird es nicht laufen ... der größere Teil der Code-Simulation einschließlich ctypes
C++/Python-Schnittstelle weggelassen, weil es zu kompliziert ist):
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)))
Das Problem ist, dass Sie alle Zahlen herum und offen halten. Wenn Sie die "pyplot" State-Machine-Schnittstelle verwenden möchten, müssen Sie die Figuren jedes Mal explizit schließen. Andernfalls werden sie beibehalten, sodass sie beim Aufruf von "plt.show" angezeigt werden können. Zur schnellen Lösung rufen Sie 'plt.close()' nach 'plt.savefig' auf. –
Ahoj Prokope, probieren Sie einen anderen Weg, um Matplotlib zu nutzen >>> ** ['Interaktive Anwendungen mit Matplotlib; Benjamin V. Root, (2015) '] ** – user3666197
Als eine Vorspeise, kann viel Spaß beim Betrachten eines eingebetteten MVC - ** live-'matplotlib'-GUI-Beispiel >>> http://stackoverflow.com/a/25769600/3666197 ** – user3666197