Ich habe eine große Anzahl von Datendateien und jede aus einer Datendatei geladenen Daten werden hunderte Male neu abgetastet und mit verschiedenen Methoden verarbeitet. Ich habe numpy
verwendet, um dies zu tun. Was ich vor mir habe, ist der Speicherfehler nach dem Ausführen der Programme mehrere Stunden. Da jede Daten separat verarbeitet werden und die Ergebnisse in einer .mat
Datei mit scipy.savemat
gespeichert werden, denke ich, dass der Speicher von früheren Daten freigegeben werden kann, so dass ich del variable_name
+ gc.collect()
verwendet, aber das funktioniert nicht. Dann habe ich multiprocessing
Modul verwendet, wie in this post und this post vorgeschlagen, funktioniert es immer noch nicht.Wie effektiv Speicher in Python freigeben?
Hier sind meine Hauptcodes:
import scipy.io as scio
import gc
from multiprocessing import Pool
def dataprocess_session:
i = -1
for f in file_lists:
i += 1
data = scio.loadmat(f)
ixs = data['rm_ix'] # resample indices
del data
gc.collect()
data = scio.loadmat('xd%d.mat'%i) # this is the data, and indices in "ixs" is used to resample subdata from this data
j = -1
mvs_ls_org = {} # preallocate results files as dictionaries, as required by scipy.savemat.
mvs_ls_norm = {}
mvs_ls_auto = {}
for ix in ixs:
j += 1
key = 'name%d'%j
X = resample_from_data(data,ix)
mvs_ls_org[key] = process(X)
scio.savemat('d%d_ls_org.mat'%i,mvs_ls_org)
del mvs_ls_org
gc.collect()
j = -1
for ix in ixs:
j += 1
key = 'name%d'%j
X = resample_from_data(data,ix)
X2 = scale(X.copy(), 'norm')
mvs_ls_norm[key] = process(X2)
scio.savemat('d%d_ls_norm.mat'%i,mvs_ls_norm)
del mvs_ls_norm
gc.collect()
j = -1
for ix in ixs:
j += 1
key = 'name%d'%j
X = resample_from_data(data,ix)
X2 = scale(X.copy(), 'auto')
mvs_ls_auto[key] = process(X2)
scio.savemat('d%d_ls_auto.mat'%i,mvs_ls_auto)
del mvs_ls_auto
gc.collect()
# use another method to process data
j = -1
mvs_fcm_org = {} # also preallocate variable for storing results
mvs_fcm_norm = {}
mvs_fcm_auto = {}
for ix in ixs:
j += 1
key = 'name%d'%j
X = resample_from_data(data['X'].copy(), ix)
dp, _ = process_2(X.copy())
mvs_fcm_org[key] = dp
scio.savemat('d%d_fcm_org.mat'%i,mvs_fcm_org)
del mvs_fcm_org
gc.collect()
j = -1
for ix in ixs:
j += 1
key = 'name%d'%j
X = resample_from_data(data['X'].copy(), ix)
X2 = scale(X.copy(), 'norm')
dp, _ = process_2(X2.copy())
mvs_fcm_norm[key] = dp
scio.savemat('d%d_fcm_norm.mat'%i,mvs_fcm_norm)
del mvs_fcm_norm
gc.collect()
j = -1
for ix in ixs:
j += 1
key = 'name%d'%j
X = resample_from_data(data['X'].copy(), ix)
X2 = scale(X.copy(), 'auto')
dp, _ = process_2(X2.copy())
mvs_fcm_auto[key] = dp
scio.savemat('d%d_fcm_auto.mat'%i,mvs_fcm_auto)
del mvs_fcm_auto
gc.collect()
Dies ist der erste Weg, die ich getan habe. Ich spaltete file_lists
in 7 Teile und lief 7 Python-Bildschirme, da mein Computer 8 CPU-Kerne hat. Kein Problem in MATLAB, wenn ich auf diese Weise mache. Ich kombiniere die Iterationen nicht über ixs
für jede Datenprozessmethode, weil der Speicherfehler auftreten kann, also lief ich resample_from_data
und speicherte die Ergebnisse separat. Da der Speicher Fehler bestehen bleibt, habe ich Pool
Klasse:
pool = Pool(processes=7)
pool.map(dataprocess_session_2, file_lists)
die die Iteration über file_lists
parallelisiert mit Dateinamen in file_lists
als Eingaben lief.
Alle Codes werden in openSuSE
mit python 2.7.5
, 8 cores CPU
und 32G RAM
ausgeführt. Ich habe top
verwendet, um den verwendeten Speicher zu überwachen. Alle Matrizen sind nicht so groß und es ist in Ordnung, wenn ich irgendeine der geladenen Daten unter Verwendung aller Codes abspiele. Aber nach mehreren Iterationen über file_lists
fällt der freie Speicher dramatisch. Ich bin sicher, dass dieses Phänomen nicht von den Daten selbst verursacht wird, da kein so großer Speicher verwendet werden sollte, selbst wenn die größte Datenmatrix verarbeitet wird. Daher vermutete ich, dass die oben beschriebenen Möglichkeiten, den Speicher freizugeben, der durch die Verarbeitung der vorherigen Daten sowie die Speicherung der Verarbeitungsergebnisse verwendet wurde, den Speicher nicht wirklich freigegeben haben.
Irgendwelche Vorschläge?
Warum wurde ich downvoted? – Elkan
Ich muss das wirklich selbst lesen, aber ich denke nicht, dass du die Hand des 'GC' auf diese Weise erzwingen kannst. Python verwendet die Referenzzählung, um zu entscheiden, ob Objekte gelöscht werden sollen. Daher entfernt 'gc.collect()' diese Objekte wahrscheinlich nicht sofort. Sie könnten mehr Hoffnung haben, wenn Sie jede dieser Schleifen in ihre eigenen Funktionen zerlegen würden, die die Daten nicht zurückgeben, aber Sie sollten dies nur als Hilfe nehmen, um weiter auf Python GC zu lesen, da ich gut dran sein könnte dieser Vorschlag. Hoffentlich kann jemand, der besser informiert ist, klären. – roganjosh
Update zu Ihrem Vorschlag: Ich versuche jetzt, obwohl kein Fehler auftritt, aber nach dem Ausführen meiner Datensätze für diese zwei Tage, nur einige KB Speicher (im Vergleich zu 32G RAM meines PCs) freigelassen wird. Da die verarbeiteten Daten eine relativ geringe Größe haben, befürchte ich, dass die Speicherkapazität immer noch erschöpft ist. – Elkan