18

メモリ不足になるコードを try/except ブロックでラップしました。ただし、MemoryError が生成されますが、キャッチされません。

次のコードがあります。

    while True:
        try:
            self.create_indexed_vocab( vocab )
            self.reset_weights()
            break;
        except MemoryError:
            # Stuff to reduce size of vocabulary
            self.vocab, self.index2word = None, None
            self.syn0, self.syn1 = None, None

            self.min_count += 1
            logger.info( ...format string here... )

次のトレースバックが表示されます。

File "./make_model_tagged_wmt11.py", line 39, in <module>
  model.build_vocab(sentences)
File "/root/CustomCompiledSoftware/gensim/gensim/models/word2vec.py", line 236, in build_vocab
  self.reset_weights()
File "/root/CustomCompiledSoftware/gensim/gensim/models/word2vec.py", line 347, in reset_weights
  self.syn0 += (random.rand(len(self.vocab), self.layer1_size) - 0.5) / self.layer1_size
File "mtrand.pyx", line 1044, in mtrand.RandomState.rand (numpy/random/mtrand/mtrand.c:6523)
File "mtrand.pyx", line 760, in mtrand.RandomState.random_sample (numpy/random/mtrand/mtrand.c:5713)
File "mtrand.pyx", line 137, in mtrand.cont0_array (numpy/random/mtrand/mtrand.c:1300)
MemoryError

Ubuntu 12.04でPython 2.7.3を実行しています

このreset_weightsself.syn0は、まさに例外が発生することを期待している行です (大きな配列を割り当てます)。不可解なことは、メモリエラーをキャッチできず、配列サイズを小さくすることを実行できないことです。

MemoryError捕まえられない特別な状況はありますか?

4

1 に答える 1

17

基礎となるメモリ管理アーキテクチャ (C の malloc() 関数) のため、インタプリタは常にこの状況から完全に回復できるとは限らないことに注意してください。それにもかかわらず、ランナウェイ プログラムが原因である場合に備えて、スタック トレースバックを出力できるように、例外が発生します。

(ドキュメントを参照)

それでも、通常は MemoryErrors をキャッチできます。MemoryError がスローされたときに正確に何が起こるかを知らなければ、実際にファンがヒットし、それを処理するためのメモリがなくなったときにそれをキャッチできない可能性があると思います。

また、実際には回復できない可能性があるため (上記を参照)、それをキャッチしてもあまり意味がありません。リストのサイズを制限するなどして、メモリが不足したり、プログラムが使用するメモリの量を制限したりすることは絶対に避けてください。

于 2013-11-11T15:13:58.973 に答える