8

私のアプリケーションでは、100 個の numpy 配列 (それぞれ 1000 個の複雑な要素) が生成され、データが入力されます。その後、何度も繰り返し、配列要素が何度も変更されます。初期生成後、システム モニターは約 50 Mb の RAM 使用量を報告します。私は新しい配列を生成していませんが、フットプリントは反復ごとに約 40 Mb 増加し続けています。

ここで、ガベージ コレクターが numpy 配列を処理しないことを学びました。したがって、データを操作するために生成している一時配列の一部が正しく収集されていないと思います。

残念ながら、 guppy.hpy ().heap() は numpy のプロファイリングに役立たないことが示されています。

問題の原因を特定し、理想的には何回繰り返しても消費量を一定に保つにはどうすればよいでしょうか?

hereで説明されているように配列要素を割り当てるときにコピーを生成している可能性があると思われます。これはガベージコレクションされません。

ガベージ コレクションを支援するために、一時的な numpy 配列を手動で破棄できますか?

[更新 1]: サンプルコード

このコードは何千回も呼び出されます。そのたびにフットプリントが増えます。私の理解では、既存の配列を読み取り、他の既存の配列を操作しているだけなので、その理由はわかりません。これらのスライス操作のいずれかが意図しないことを行っていますか? (行が長くて申し訳ありません。単純化できますが、エラーを隠している可能性もあります。)

for ts in np.arange(numTimeslots):
            for fc in np.arange(numFreqChunks):
                interfencep = np.sum( np.dot(np.dot(self.baseStations[bs].cells[cell].CSI_OFDMA[:,:,fc,ts] ,np.diag(cell.OFDMA_power[:,fc,ts])),self.baseStations[bs].cells[cell].CSI_OFDMA[:,:,fc,ts].conj().T) for bs in self.baseStations for cell in bs.cells if cell != self._cell) 
                noisep = np.eye(self.antennas) * (self.noisePower / numFreqChunks)
                self.OFDMA_interferenceCovar[:,:,fc,ts] = noisep + interfencep
                self.OFDMA_EC[:,:,fc,ts] = (np.dot(np.dot(self.OFDMA_CSI[:,:,fc,ts],linalg.inv(noisep+interfencep)),self.OFDMA_CSI[:,:,fc,ts].conj().T))
                eigs = linalg.eig(self.OFDMA_EC[:,:,fc,ts])[0]
                self.OFDMA_SINR[:,fc,ts] = np.real(eigs)

[更新 2]: 興味のある方のために説明すると、これはモバイル ネットワーク シミュレーターの一部です。virtualenv、Python 2.7.3、Numpy 1.6.2、SciPy 0.11.0b1 で実行

[更新 3]: コメントを付けてシステム モニターを確認すると、「interferencep = ...」行が原因であることがわかります。解放されていない重要なメモリが割り当てられました。しかし、なぜ?

4

2 に答える 2

6

私は同じ種類の問題を抱えていました。残念ながら、回避策は見つかりませんでした。私にとってうまくいった唯一のことは、コードを小さな分離された関数にリファクタリングすることでした。これらの関数は、ガベージ コレクターが配列を収集するのを妨げる配列への参照を保持していないことを確信できるように作成する必要があります。スライスなどによって生成される配列ビューには特に注意する必要があります ...

コードのメモリ効率を高め、メモリ リークを起こしにくくするために、多くの numpy 関数で提供される out= キーワード引数を使用すると便利であることがよくありました。

于 2012-09-14T11:06:23.497 に答える
2

システム モニターとコード インスペクション/コメントを使用して、メモリ リークを発見しました。これは、numpy 配列を別のファイルの空のリストと比較したことが原因でした。別の場所でリークを掘り下げて、この質問を削除することに投票します。

[更新 1]: 問題の原因を説明する新しい質問: numpy 配列とリストを比較すると、大量のメモリが消費されるのはなぜですか?

于 2012-09-17T13:32:13.373 に答える