web-dev-qa-db-ja.com

numpy配列をNoneに設定するとメモリが解放されますか?

(600、800)や(3、600、800)shape'dのような何百もの本当に大きな行列があります。

そのため、使用するメモリが不要になり次第、使用したメモリの割り当てを解除します。

私は思った:

_some_matrix = None
_

ジョブを実行する必要がありますか、それとも参照はなしに設定されていますが、メモリのどこかにスペースがまだ割り当てられていますか? (将来的に_some_matrix_の再初期化のために割り当てられたスペースを保持するなど)

さらに:時々、マトリックスをスライスし、何かを計算して、値をバッファー(常に追加されるため、リスト)に入れます。リストをNoneに設定すると、メモリが確実に解放されますよね?

または、識別子全体とその参照オブジェクトが「削除」されるような何らかのunset()メソッドが存在しますか?

16
daniel451

garbage collection をぜひご覧ください。 pythonにはガベージコレクションがあり、C/C++のような一部のプログラミング言語とは異なり、スペースが不要になったときにプログラマーが動的に割り当てたメモリを自分で解放する必要があります。 necessaryのときにpython自体がメモリを解放することを意味します。

some_matrix = Noneを使用すると、変数がメモリ空間からリンク解除されます。参照カウンタが減少し、0に達すると、ガベージコレクタはメモリを解放します。 MSeifertが提案するdel some_matrixを使用すると、答えが示すものとは異なり、メモリはすぐには解放されません。 python doc によると、これが起こることです:

名前を削除すると、ローカルまたはグローバル名前空間からその名前のバインディングが削除されます

内部で起こったことは、メモリ空間への参照のカウンタが、Noneの割り当てやdelの使用とは別に1だけ減少することです。このカウンタが0に達すると、ガベージコレクタは将来freeのメモリスペースを使用します。唯一の違いは、delを使用する場合、名前からもう名前が不要であることはコンテキストから明らかです。

ガベージコレクションのドキュメントを見ると、ガベージコレクションを自分で呼び出すか、パラメータの一部を変更できることがわかります。

18
innoSPG

Numpyは、参照カウンターがゼロの場合に配列を削除します(または少なくとも参照カウンターを追跡し、OSがガーベッジを収集できるようにします)。

たとえば

import numpy as np
a = np.linspace(0,100, 10000000)
a = None

メモリを「即座に」解放します(優先方法はdel aしかし)

import numpy as np
a = np.linspace(0,100, 10000000)
b = a
a = None

何も解放しません。


スライスについても言及しました。スライスはデータの単なるビューであるため、2番目の例とまったく同じです。同じ配列を参照する両方の変数を削除しない場合、OSは配列を保持します。

非常にメモリを消費する何かを行う場合、操作を実行し、本当に必要なものだけを返す別個の関数に常に固執します。中間結果が解放されるように、関数はそれ自体をクリーンアップします(返されない場合)。

7
MSeifert

aのコピーが暗黙的に作成されますが、以下のような何かをする必要がある場合、メモリは解放されません。

a = np.ones((10000, 10000))
b = np.empty((10000, 10000))
b[:] = a
a = None
del a

代わりに次のことができ、a = Noneを実行した後にメモリが解放されます:

a = np.ones((10000, 10000))
b = np.empty((10000, 10000))
b[:] = np.copy(a)
a = None
del a
0
Amir