我已经使用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_weights
行self.syn0
正好是我期望引发异常的行(它分配一个大数组)。令人费解的是,我无法捕获内存错误并做一些会使数组大小变小的事情。
是否存在导致MemoryError
无法被抓住的特殊情况?
答案 0 :(得分:15)
请注意,由于底层内存管理架构(C的malloc()函数),解释器可能无法始终从这种情况中完全恢复;然而,它会引发一个异常,以便可以打印堆栈回溯,以防止失控程序。
(见the docs)
通常,您可以捕获MemoryErrors。在不知道MemoryError被抛出后到底发生了什么时,我猜你可能无法抓住它,因为狗屎真的击中了粉丝并且没有更多的内存来处理它。
此外,由于你可能无法真正从中恢复(见上文),因此抓住它可能没有多大意义。 你应该真的避免内存不足并限制程序使用的内存量,例如:只允许列表的大小有限。