4

Pythonがどのようにメモリとガベージコレクトを割り当てるのか、そしてそれがどのようにプラットフォーム固有であるのか、私は少し戸惑っています。たとえば、次の2つのコードスニペットを比較すると、次のようになります。

スニペットA:

>>> id('x' * 10000000) == id('x' * 10000000)
True

スニペットB:

>>> x = "x"*10000000
>>> y = "x"*10000000
>>> id(x) == id(y)
False

スニペットAはtrueを返します。これは、Pythonがメモリを割り当てるときに、最初のテストでは同じ場所に割り当て、2番目のテストでは異なる場所に割り当てるため、メモリの場所が異なるためです。

しかし、これを大規模に試してみると、システムのパフォーマンスやプラットフォームがこれに影響を与えるようです。

for i in xrange(1, 1000000000):
    if id('x' * i) != id('x' * i):
        print i
        break

Macの友達がこれを試し、最後まで実行しました。たくさんのLinuxVMで実行すると、常に異なるVMで(ただし異なる時間に)返されます。これは、Pythonでのガベージコレクションのスケジュールが原因ですか?Linux VMの処理速度がMacよりも遅いためですか、それともLinux Pythonの実装でガベージコレクションが異なるためですか?

4

3 に答える 3

6

ガベージコレクターは、都合のよいスペースを使用するだけです。さまざまなガベージコレクション戦略があり、パラメータ、さまざまなプラットフォーム、メモリ使用量、月の満ち欠けなどの影響も受けます。インタプリタが特定のオブジェクトを割り当てる方法を推測しようとすると、時間の無駄になります。

于 2012-10-30T19:45:04.380 に答える
5

これは、Pythonが小さな整数と文字列をキャッシュするために発生します。

大きな文字列:キャッシュされていない変数に格納されます:

In [32]: x = "x"*10000000

In [33]: y = "x"*10000000

In [34]: x is y
Out[34]: False

大きな文字列:変数に格納されておらず、キャッシュされているように見えます:

In [35]: id('x' * 10000000) == id('x' * 10000000)
Out[35]: True

小さな文字列:キャッシュ

In [36]: x="abcd"

In [37]: y="abcd"

In [38]: x is y
Out[38]: True

小整数:キャ​​ッシュ

In [39]: x=3

In [40]: y=3

In [41]: x is y
Out[41]: True

大きな整数:

変数に格納:キャッシュされません

In [49]: x=12345678

In [50]: y=12345678

In [51]: x is y
Out[51]: False

保存されません:キャッシュされます

In [52]: id(12345678)==id(12345678)
Out[52]: True
于 2012-10-30T19:50:41.000 に答える
3

CPythonは、メモリ管理に2つの戦略を使用します。

  1. 参照カウント
  2. マークアンドスイープガベージコレクション

割り当ては通常、プラットフォームのmalloc / free関数を介して行われ、基盤となるランタイムのパフォーマンス特性を継承します。メモリを再利用するかどうかは、オペレーティングシステムによって決定されます。(Python vmによってプールされるオブジェクトがいくつかあります)

ただし、この例では、「実際の」GCアルゴリズムはトリガーされません(これは、サイクルを収集するためにのみ使用されます)。最後の参照が削除されるとすぐに、長い文字列の割り当てが解除されます。

于 2012-10-30T19:50:16.400 に答える