私は、メモリに保持されている大きなリストからデータにアクセスすることを含むプロジェクトに取り組んでいます。リストは非常にボリュームがあるので(何百万行も)、私はどのくらいのメモリが使用されているかを見守ります。 OS Xを使用しているので、これらのリストを作成するときにアクティビティモニターを開いたままにしておきます。Pythonリストの異常なメモリ使用
リストで使用されるメモリの量は、構築方法によって大きく異なることがありますが、その理由を理解できないようです。いくつかのサンプルコードのための今すぐ
:
は、最初の関数は、以下のリストを作成し、すべて同じ3つの乱数でそれを埋める(私はOSX 10.8.3でPython 2.7.4を使用しています)。
以下の2番目の関数は、リストを作成し、すべての異なる乱数でリストを作成します。
import random
import sys
def make_table1(size):
list1 = size *[(float(),float(),float())] # initialize the list
line = (random.random(),
random.random(),
random.random())
for count in xrange(0, size): # Now fill it
list1[count] = line
return list1
def make_table2(size):
list1 = size *[(float(),float(),float())] # initialize the list
for count in xrange(0, size): # Now fill it
list1[count] = (random.random(),
random.random(),
random.random())
return list1
(最初に私は上記のコードは、はるかに効率的に書かれている可能性が実現することとしましょう。それは、可能な限り類似したように2つの例を維持するために、このように書かれています。)
今、私はいくつかのリストを作成しますこれらの関数を使用して:
In [2]: thing1 = make_table1(6000000)
In [3]: sys.getsizeof(thing1)
Out[3]: 48000072
をこの時点で、私の記憶では、私は上記の情報に期待するものは約46メガバイトでジャンプを使用していました。
は今、次の機能のために:あなたが見ることができるように
In [4]: thing2 = make_table2(6000000)
In [5]: sys.getsizeof(thing2)
Out[5]: 48000072
、二つのリストに取り込まれたメモリは同じです。彼らはまさに同じ長さなので、それは予想されます。私が期待していなかったことは、アクティビティモニターで使用されたメモリを1 GB以上にジャンプしたことです!
私はいくつかのオーバーヘッドがあると思いますが、20倍もあると思いますか? 46MBのリストでは1GB?
真剣に?
In [5]: import gc
In [6]: gc.collect()
Out[6]: 0
は、それが使用されるメモリの量をゼロに違いを作っ:診断へのオーケー
、...
私が試した最初のものは、任意のゴミを収集することです。
次私はメモリが起こっている場所を確認するためにグッピーを使用:タプルのの
462メガバイト(でしょ?)
412:
In [7]: from guppy import hpy
In [8]: hpy().heap()
Out[8]:
Partition of a set of 24217689 objects. Total size = 1039012560 bytes.
Index Count % Size % Cumulative % Kind (class/dict of class)
0 6054789 25 484821768 47 484821768 47 tuple
1 18008261 74 432198264 42 917020032 88 float
2 2267 0 96847576 9 1013867608 98 list
3 99032 0 11392880 1 1025260488 99 str
4 585 0 1963224 0 1027223712 99 dict of module
5 1712 0 1799552 0 1029023264 99 dict (no owner)
6 13606 0 1741568 0 1030764832 99 types.CodeType
7 13355 0 1602600 0 1032367432 99 function
8 1494 0 1348088 0 1033715520 99 type
9 1494 0 1300752 0 1035016272 100 dict of type
<691 more rows. Type e.g. '_.more' to view.>
大丈夫、私の記憶が取り込まれますフロートのMB(何?)リストの
92 MB(さて、この1つは理にかなっています。2 * 46メガバイト= 92)
私のリストはあらかじめ割り当てられているので、過剰割り当てがあるとは思わない。
質問:
なぜこれほど異なるこれら2つの非常に類似したリストが使用するメモリの量は?
あまりオーバーヘッドのないリストを作成する別の方法はありますか?
メモリをすべて解放する方法はありますか?
注:ディスクに保管するか、array.arrayまたはnumpyまたはpandasデータ構造を使用することをおすすめしないでください。それらはすべて素晴らしいオプションですが、この質問はそれらに関するものではありません。この質問は普通の古いリストに関するものです。
私はPython 3.3で同様のコードを試しましたが、結果は同じです。
ここにはsimilar problemの人がいます。それはいくつかのヒントを含んでいますが、同じ質問ではありません。
ありがとうございました!
あなたのサイズ×3 6000000の2D配列に興味を持っているようです。あなたはnumpyを見ましたか?(例: 'numpy.random.rand(6000000、3)') – SingleNegationElimination