如何记录python MemoryError(当我内存不足时)

时间:2013-10-19 18:37:26

标签: python memory logging exception-handling out-of-memory

作为我的一个程序的一部分,我想抓住任何MemoryError并记录它们。目前,我正在使用traceback.format_exception格式化所有其他异常;我也想为MemoryError做这件事。

然而,使用format_exception需要使用更多内存,这正是我内存不足时无法做到的。

做什么?

除了终止MemoryError之外,我还能做什么?理想情况下,我会记录它们然后恢复程序,假设释放处理程序和thrower *之间的堆栈部分已经释放了足够的内存供我这样做。

(*并且那些堆对象只能通过从堆栈部分发出的引用保持活动状态)

3 个答案:

答案 0 :(得分:4)

它与“堆栈”没什么关系。当系统MemoryError(或类似的平台函数)返回malloc()时,Python会引发NULL。在这种情况下,实际上没有分配新内存!因此,您可以获得与触发MemoryError的请求之前一样多的可用内存。例如,在32位框上的交互式shell中:

>>> x = [None] * 10**9
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
MemoryError
>>>

那是无害的。是的,在一个真实的程序中,当堆栈展开时,其他内存可能会被释放。

但是,如果再次尝试相同(或类似)的任务,“只是继续”不会导致另一个MemoryError,那么你的程序肯定会出现异常。确实通常会退出计划并重新开始。

@ FredMitchell保留一些“紧急记忆”的想法可能值得追求。如,

emergency = 'x' * 10**7

消耗大约10 MB(在Python 2中),主要是“一大块”,你的处理程序可以做

emergency = ""

将其释放回系统。然后malloc()将有一个10MB的新连续块来处理。

但是,最后,我敢打赌它会更容易退出; - )

答案 1 :(得分:2)

食谱我们最终使用了:

def do_a_generic_memory_hungry_thing(specific_context):
    memory_error = MemoryError(str(specific_context)) # pre-allocate it
    try: memory_hungry_stuff()
    except MemoryError: raise memory_error

事实证明,memory_hungry_stuffexcept之间的痕迹并不有趣;有趣的部分是specific_context,所以在这种情况下进行预分配是两个。

注意:我们遇到了尝试打印(确实:格式化)memory_error的内存错误,因此这不是防弹。也许结合发布一个dud字符串,它就可以解决问题。

答案 2 :(得分:1)

一般情况下,内存不足错误可能是您程序中最棘手的问题,因为您不在主要资源之内,可以让您做任何事情。也许该程序可以在一个脚本中运行,该脚本从输出中检测故障并记录它。

可以尝试使用一些内存,其唯一目的是在内存不足错误时“释放”。但我对python中的这种方法并不乐观。