39

多くの場合、あなたは間違いなくリストを二度と使用しないと確信しています.今すぐメモリが解放されることを願っています.

a = [11,22,34,567,9999]
del a

本当にメモリを解放するかどうかはわかりませんが、使用できます

del a[:]

リスト a 内のすべての要素を実際に削除します。

リリースする最良の方法はこれですか?

def realse_list(a):
   del a[:]
   del a

あなたの意見が必要です。

ところで、タプルとセットはどうですか?

4

5 に答える 5

52
def release_list(a):
   del a[:]
   del a

これは絶対にしないでください。Python は、参照されなくなったすべてのオブジェクトを自動的に解放するためdel a、リストが他の場所で参照されていない場合、簡単にリストのメモリが解放されることが保証されます。その場合、個々の項目の一部がまだ参照されていない限り、個々のリスト項目も解放されます (およびそれらからのみ参照されているすべてのオブジェクトなど)。

つまり、リストが他の場所で参照されている場合にのみdel a[:]; del a、それ自体よりも多くのものが解放されます。del aこれはまさに、リストを空にしてはならないときです: 他の誰かがまだそれを使用しています!!!

基本的に、メモリの断片の管理について考えるべきではありません。代わりに、オブジェクトへの参照の管理について考えてください。すべての Python コードの 99% で、Python は最後に必要になった直後に不要なものをすべてクリーンアップします。問題はありません。関数がその関数内のすべてのローカル変数を終了するたびに「死にます」。他のどこにも参照されていないオブジェクトを指していた場合、それらは削除され、それらのオブジェクトに含まれるすべてのものにカスケードされます。

これについて考える必要があるのは、大きなオブジェクト (巨大なリストなど) があり、それを使って何かを行い、長時間 (またはメモリを集中的に使用する) サブ計算を開始するときだけです。サブ計算には必要ありません。それへの参照があるため、大きなオブジェクトは、サブ計算が終了して戻るまで解放されません。そのような場合 (およびそのような場合のみdel)は、サブ計算を開始する前にラージ オブジェクトへの参照を明示的に行うことができます。発信者があなたにオブジェクトを渡し、あなたが戻った後も発信者それを必要としている場合、あなたは非常に発売されなくてよかった)。

于 2012-09-14T03:19:02.733 に答える
7

@monkut が指摘しているように、ほとんどの場合、メモリ管理についてあまり心配する必要はありません。巨大なリストがある場合は、これで完了であり、しばらくの間現在の関数のスコープから外れることはありません:

del aaそのメモリのチャンクの名前を削除するだけです。他の関数や構造体、またはそれへの参照がまだある場合、それは削除されません。このコードの名前の下にそのリストへの唯一の参照があり、aCPython を使用している場合、参照カウンターはすぐにそのメモリを解放します。他の実装 (PyPy、Jython、IronPython) は、ガベージ コレクターが異なるため、すぐには強制終了しない可能性があります。

このため、呼び出し元がまだ参照を持っているため、関数内のdel aステートメントrealse_listは実際には何もしません!

del a[:]お気づきのように、リストから要素を削除するため、おそらくそのメモリ使用量のほとんどが削除されます。

the_set.clear()セットで同様の動作を行うことができます。

タプルは不変であるため、del the_tuple他の誰も参照していないことを願っていますが、おそらく巨大なタプルを持つべきではありません!

于 2012-09-14T03:00:25.987 に答える
6

Python は参照カウントを使用してそのリソースを管理します。

import sys
class foo:
    pass

b = foo()
a = [b, 1]

sys.getrefcount(b)  # gives 3
sys.getrefcount(a)  # gives 2

a = None  # delete the list
sys.getrefcount(b)  # gives 2

上記の例では、リストに入れると b の参照カウントがインクリメントされ、リストを削除すると b の参照カウントも減少します。だからあなたのコードで

def release_list(a):
   del a[:]
   del a

冗長でした。

要約すると、リストを None オブジェクトに割り当てるか、 del キーワードを使用して属性辞書からリストを削除するだけです。(別名、実際のオブジェクトから名前をバインド解除します)。例えば、

a = None # or
del a

オブジェクトの参照カウントがゼロになると、Python がメモリを解放します。オブジェクトが確実に削除されるようにするには、他の場所がオブジェクトを名前またはコンテナーで参照していないことを確認する必要があります。

sys.getrefcount(b) # gives 2

sys.getrefcountが 2 を返した場合、それはオブジェクトの参照を持っていたのはあなただけであり、いつ参照したかを意味します。

b = None

メモリから解放されます。

于 2012-09-14T03:56:00.170 に答える
2

データ型のメモリ管理とパフォーマンスが心配な場合は、リンクされた二重キューのようなものを使用しないでください。

まず、そのメモリ フットプリントはメモリ全体に散らばっているため、すぐに大量の連続メモリを割り当てる必要はありません。

次に、エンキューとデキューのアクセス時間が短縮されます。これは、標準のリストとは異なり、中央の要素を削除すると、リストの残りの部分をインデックスにスライドさせる必要がないためです。これは、大きなリストでは時間がかかります。

また、整数のみを使用している場合は、バイナリ ヒープを調べることをお勧めします。これは、リストを使用したほとんどの O(N) と比較して、O(log^2n) アクセス時間が表示されるためです。

于 2012-09-14T03:47:54.293 に答える