私のアプリケーションでは、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 = ...」行が原因であることがわかります。解放されていない重要なメモリが割り当てられました。しかし、なぜ?