2

私はかなり長い間Pythonを使用してきましたが、ガベージコレクション、メモリ管理、および変数の削除とメモリの解放に関する実際の問題のいくつかの問題について混乱しています。

>>> pop = range(1000)
>>> p = pop[100:700]
>>> del pop[:]
>>> pop
[]
>>> p
[100.. ,200.. 300...699]

上記のコードでは、これが発生します。だが、

>>> pop = range(1000)
>>> k = pop   
>>> del pop[:]
>>> pop 
[]
>>> k
[]

ここで2番目のケースでは、kがリスト'pop'を指していることを意味します。

質問の最初の部分:

しかし、最初のコードブロックで何が起こっているのでしょうか?[100:700]要素を含むメモリは削除されませんか、それともリスト'p'の作成時に複製されますか?

質問の2番目の部分:

また、可能な限りgc.enableステートメントとgc.collectステートメントを間に入れてみましたが、両方のコードでメモリ使用率に変化はありません。これはちょっと不可解です。Pythonが空きメモリをOSに戻さないのは悪いことではありませんか?私が行った小さな研究で私が間違っている場合は、私を訂正してください。前もって感謝します。

4

2 に答える 2

5

シーケンスをスライスすると、適切な要素の浅いコピーを含む新しいシーケンスが作成されます。

スクリプトが向きを変えて新しいオブジェクトを作成する可能性があるため、メモリをOSに戻すのは悪い場合があります。その時点で、PythonはOSにメモリを再度要求する必要があります。

于 2012-06-26T09:10:28.180 に答える
1

前編:

最初のコードブロックでは、古いオブジェクトの要素をコピーしてから削除する新しいオブジェクトを作成します。

ただし、2番目のコードブロックでは、同じオブジェクトへの参照を別の変数に割り当てるだけです。次に、リストを空にします。もちろん、両方の参照から表示されます。

2番目の部分:メモリは適切な場合に返されますが、常に返されるわけではありません。Pythonの内部には、メモリの出所を制御するメモリアロケータがあります。2つの方法があります:brk()/sbrk()メカニズムを介して(より小さなメモリブロックの場合)および経由mmap()(より大きなブロックの場合)。

ここでは、データセグメントの最後に直接割り当てられるかなり小さなブロックがあります。

datadatadata object1object1 object2object2

object1のみを解放すると、次のオブジェクトに再利用できるメモリギャップがありますが、簡単に解放してOSに戻すことはできません。

両方のオブジェクトを解放すると、メモリが返される可能性があります。しかし、すべてをすぐに返すことは最善のことではないため、おそらくしばらくの間メモリを元に戻すためのしきい値があります。

于 2012-06-26T09:18:04.363 に答える