Mam skrypt Pythona, który robi wiele symulacji dla różnych parametrów (Q
, K
), działki wyników i zapisuje go na dysku.Numpy i matplotlib garbage collection
Każdy zestaw parametrów (Q,K
) generuje trójwymiarową siatkę wolumetryczną danych o punktach danych 200x200x80, która wymaga ~ 100 MB danych. Część tej wolumetrycznej siatki jest następnie spiętrzana, warstwa po warstwie, co daje ~ 60 obrazów.
Problem polega na tym, że python oczywiście nie zwalnia pamięci podczas tego procesu. Nie jestem pewien, gdzie jest wyciek pamięci lub jakie reguły decydują o tym, w jaki sposób python decyduje, które obiekty są deallokowane. Nie jestem również pewien, czy pamięć zostanie utracona w tablicach numpy
lub obiektach figur matplotlib
.
- Czy istnieje prosty sposób analizować który obiektów w python utrzymują się w pamięci i które zostały automatycznie zwalniane?
- Czy istnieje sposób zmuszenia Pythona do zwolnienia wszystkich tablic i obiektów figur, które zostały utworzone w określonym cyklu pętli lub w konkretnym wywołaniu funkcji?
Odpowiedni fragment kodu jest tutaj (jednak nie będzie działać ... im większa część kodu symulacyjnego tym ctypes
C++/interfejs Pythona zostanie pominięty, ponieważ jest to zbyt skomplikowane):
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)))
Problem polega na tym, że wszystkie liczby są otwarte i otwarte. Jeśli zamierzasz używać interfejsu stanu maszyny "pyplot", musisz za każdym razem wyraźnie zamykać wartości. W przeciwnym razie będą one przechowywane tak, aby mogły być wyświetlane, gdy wywołasz 'plt.show'. Jako szybką naprawę wywołaj 'plt.close()' po 'plt.savefig'. –
Ahoj Prokope, spróbuj zasmakować w inny sposób, jak wykorzystać matplotlib >>> ** ["Aplikacje interaktywne przy użyciu Matplotlib; Benjamin V. Root, (2015) '] ** – user3666197
Jako przekąska, możesz cieszyć się oglądaniem wbudowanego MVC - ** live-' matplotlib'-GUI sample >>> http://stackoverflow.com/a/25769600/3666197 ** – user3666197