如何找出使用PIL函数导致内存错误的原因?

时间:2011-10-14 01:31:04

标签: python memory python-imaging-library

我正在使用PIL(python图像库)进行一些图像处理,特别是我将图像拼接在一起。

我的代码似乎适用于少量的一些图像,但有时我得到MemoryError

对我来说特别陌生的部分是我没有对位图进行操作,所有这些都适用于10kb以下的< 10张图像。

我正在拨打Image.resize的电话,但我很惊讶这有很多问题。

这是堆栈轨道:

Traceback (most recent call last):                                                                                                                                               
  File "test.py", line 15, in <module>                                                                                                                                           
    pprint(scale_matrix_down((90,90), [inpt]))                                                                                                                                   
  File "/Users/jeremykarmel/Desktop/Python/merger.py", line 105, in scale_matrix_down                                                                                            
    return [shrinkRow(row, row_width_overflow(row)) for row in matrix]                                                                                                           
  File "/Users/jeremykarmel/Desktop/Python/merger.py", line 103, in shrinkRow                                                                                                    
    rest         = [shrinkIm(im, pixels_per_im) for im in row[remaining_pixels:]]                                                                                                
  File "/Users/jeremykarmel/Desktop/Python/merger.py", line 110, in shrinkIm                                                                                                     
    return im.resize((im.size[0] - num_pix, im.size[1] - num_pix))                                                                                                               
  File "/Library/Python/2.7/site-packages/PIL/Image.py", line 1302, in resize                                                                                                    
    im = self.im.resize(size, resample)                                                                                                                                          
MemoryError

请记住,图像均小于90x90像素。

我非常处于死胡同,真的不知道如何继续。我该怎么办才能释放记忆?我应该调用del运算符还是有更简单的东西可以做? 在此先感谢您的帮助!

2 个答案:

答案 0 :(得分:8)

事实证明这实际上并不是内存错误。正如Winston Ewert指出的那样,我实际上是将负参数输入图像调整大小的方法。

尽管python文档说内存错误是针对内存问题的,但是当你给负参数调整大小时会抛出这个错误。我怀疑是因为PIL大量利用C库,这些可能会导致无效输入泄漏,并且由于库不进行边界检查,因此错误只是起泡。

答案 1 :(得分:8)

解释实际发生的事情:

  1. 您尝试将图片尺寸调整为负宽度
  2. PIL尝试分配负大小的图像以适合调整大小的图像
  3. PIL调用具有负内存量的malloc以保持负大小的图像
  4. malloc采用未签名的size_t。结果,负内存请求被解释为一个非常大的数字,而不是负数。
  5. malloc无法分配大的内容,因此会产生错误
  6. 对于PIL,这看起来与内存不足错误完全相同,因此会将其报告为
  7. 因此无效输入不会导致泄漏或其他不良行为。它们会导致malloc请求错误并放弃。 PIL可以检查负数大小,从而产生更好的错误消息。也许他们觉得不值得,因为如果你这样做,它已经产生了错误信息。

    实际上,实际耗尽内存很难,因为操作系统会非常努力地保持进程,例如使用虚拟内存。在系统耗尽内存之前,系统会陷入困境。所以我发现大多数内存不足错误都是由负内存请求引起的。据我所知,我所获得的唯一真正的内存不足错误可能是因为它使用了虚拟机。