2012-05-13 11 views
1

第3ラウンドのexecutinon(ループ中)のnfindのエラーは、MemoryErrorをCACHE[sha] = numberと返しますか? システムに十分なメモリがあり、whileループのすべての端に割り当てられたメモリがクリアされますが、3回目にエラーが返され、whileループが実行されます。 これらのコードを実行すると、XRAN= 2**23を大きな値または小さい指数(1または2)に変更してエラーを生成する必要がある場合があります。 助けと提案をお願いします。辞書変数のMemoryError

from multiprocessing import Pool 
from hashlib import sha256 
from struct import pack 
import gc 

XRAN= 2**23 

def compsha(number): 
    return number, sha256(pack("Q", number)).digest() 

if __name__ == '__main__': 
    gc.enable() 
    nfind = 1 
    while (nfind > 0): 
     print(nfind) 
     CACHE = {} 
     pool = Pool() 
     for i, output in enumerate(pool.imap_unordered(compsha, xrange((nfind-1)*XRAN, nfind*XRAN), 2)): 
      number, sha = output 
      CACHE[sha] = number 
     pool.close() 
     pool.join() 
     if nfind != 0 : 
      nfind = nfind + 1 
     del CACHE 
======================================================= 
>>> 
1 
2 

Traceback (most recent call last): 
    File "D:\Python27\free_pool.py", line 20, in <module> 
    CACHE[sha] = number 
MemoryError 

答えて

1

2**23の要素を辞書に格納しようとしているため、メモリが不足しています。それは明らかにあなたが持っている以上の、多くのメモリを使用します!あなたは十分なRAMがあると言います、どのくらいあなたが必要とするかを決定しましたか?

別のアルゴリズムを用意する必要があります。

また、CACHEにアクセスするようには思われないので、どうしてそれを使用していますか?

+0

しかし、私は 'デルcache'に持つループのすべての端にメモリを解放します。また、システムエクスプローラでメモリの割り当てを監視し、ループのたびに解放されます。十分なメモリがあります。この例のコード は、この部分がこの説明に重要ではないため、使用されません。 – user1391182

+0

さて、すべてのループの後にメモリが解放されるのは当然です。それは、単一ループ内のメモリ制限でなければなりません。 – jdi

+0

@ user1391182:十分なメモリがあると思われる理由を説明できますか?明らかにあなたはしません。 –

3

あなたが使用していない辞書にあまりに多くの方法を保存するというネッドの答えに加えて、32ビットのPythonインタプリタで動作し、メインプロセスで4GBのメモリ制限に達している可能性はありますか? Windows上で

$ python -c "import sys; print sys.maxint" // 64-bit python 
9223372036854775807 

$ python-32 -c "import sys; print sys.maxint" // 32-bit 
2147483647 

、32ビットプロセスは2〜4ギガバイト

+0

これは正しい答えであると私はすべてのコメントを読んで言うと思います。 OPは、コンピュータが4GBのメモリを持っていても、約2GBのメモリ使用量でプログラムが爆発すると言っているようだ。私が思うとWindowsにとっておそらく2GBが限界です。 –

0

の間に制限されるかもしれない唯一の解放可能なように、メモリのその領域をマークdel CACHEを実行している点に注意してください - それは実際にそれを解放しません。それは来て、その記憶を解放するガベージコレクターの仕事です。ループの最後にgc.collect()を実行してみてください。

(情報開示:私はこれが何を修正することを知りませんので、私はあなたの問題を複製することはできません)

+1

これは正しいとは思わない。参照カウントの利点は、オブジェクトのrefcountがゼロに落ちたときに、そのオブジェクトをすぐに再利用できることです。 GCは、循環構造を再利用するためのものです。 –

+0

@haldean:複製については、 'XRAN = 2 ** 23 'をより大きな指数、例えば24,25、または26に変更してみてください。そして、あるポイント(ただし、最初の' while'パスではない)ではエラーが発生します。 – user1391182

+0

@NedBatchelderああ確かに正しいです。これを無視してください。 –