私は多数のデータファイルを持ち、データファイルからロードされた各データは何百回も再サンプリングされ、いくつかの方法で処理されます。これを行うにはnumpy
を使用しました。私が直面しているのは、プログラムを数時間実行した後のメモリエラーです。それぞれのデータが別々に処理され、結果はのデータが格納されているので、以前のデータで使用されていたメモリを解放できると思いますのでdel variable_name
+ gc.collect()
を使用しましたが、これは動作しません。その後、this postとthis postに示唆されているように、multiprocessing
モジュールを使用しましたが、まだ動作しません。ここでどのように効果的にPythonでメモリを解放するには?
は私のメインのコードです:
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()
これは私がやった最初の方法です。私のコンピュータは8つのCPUコアを持っているので、私はfile_lists
を7つの部分に分割し、7つのpython画面を走らせました。 このようにしてもMATLABでは問題ありません。メモリエラーが発生する可能性があるので、ixs
以上の繰り返しは組み合わせないので、resample_from_data
を実行し、結果を別々に保存しました。入力としてfile_lists
内のファイル名で並列化file_lists
以上の反復を実行した
pool = Pool(processes=7)
pool.map(dataprocess_session_2, file_lists)
:メモリエラーが解消されないように、私はとしてPool
クラスを使用していました。
すべてのコードはopenSuSE
で実行され、python 2.7.5
,8 cores CPU
および32G RAM
で実行されます。私は使用されたメモリを監視するためにtop
を使用しました。すべての行列はそれほど大きくなく、すべてのコードを使用してロードされたデータのいずれかを実行すると問題ありません。しかし、file_lists
を何度も繰り返しても、空きメモリは劇的に減少します。この現象はデータ自体に起因するものではないと私は確信しています。なぜなら、このような大きなメモリは、最大のデータ・マトリックスが処理中であっても使用されるべきではないからです。以前のデータを処理したり、処理結果を保存したりして使用したメモリを解放しようとした上記の方法では、実際にメモリが解放されていないと思われました。
提案がありますか?
なぜ私はdownvotedされましたか? – Elkan
私はこれを正しく自分自身で読む必要がありますが、私はあなたが 'gc'の手をこのように強制することはできないと思います。 Pythonは参照カウントを使ってオブジェクトを削除するかどうかを判断するので、 'gc.collect()'はおそらくそれらのオブジェクトを直ちに削除していません。これらのループのそれぞれを、データを返さない独自の関数に分解したい場合は、もっと希望があるかもしれませんが、もう一度Python gcで読むことを援助するだけです。その提案。うまくいけば、もっと精通した人が明らかにできることを望みます。 – roganjosh
あなたの提案に更新してください:エラーは発生しませんが、この2日間はデータセットを実行した後、数KBのメモリ(PCの32G RAMと比較して)のみが空きました。処理されるデータのサイズが比較的小さいので、私がこの方法で使用すると、メモリがまだ使い果たされる可能性があります。 – Elkan