Как я могу узнать, почему использование функций PIL приводит к ошибке памяти? - PullRequest
12 голосов
/ 14 октября 2011

Я использую PIL (библиотеку изображений Python), чтобы сделать некоторые манипуляции с изображениями, в частности, я склеиваю изображения вместе.

Мой код работает нормально для некоторых изображений в небольших количествах, но иногда я получаю MemoryError.

Что особенно странно для меня, так это то, что я не делаю манипуляций с битовыми изображениями, все это работает с <10 ​​изображениями размером менее 10 КБ. </p>

Я много звоню на 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 ]

8 голосов
/ 16 октября 2011

Чтобы объяснить, что на самом деле происходит:

  1. Вы пытаетесь изменить размер изображения до отрицательной ширины
  2. PIL пытается выделить изображение отрицательного размера, чтобы соответствовать измененному размеру изображения
  3. PIL вызывает malloc с отрицательным объемом памяти для хранения изображения отрицательного размера
  4. malloc принимает size_t без знака.В результате отрицательный запрос памяти интерпретируется как очень большое число, а не как отрицательное число.
  5. malloc не может выделить что-то большое, поэтому выдает ошибку
  6. Для PIL это выглядит так же, какошибка нехватки памяти, поэтому он сообщает об этом

Таким образом, неверные входные данные не вызывают утечек или другого плохого поведения.Они приводят к неправильному запросу malloc и сдаются.PIL может проверять наличие отрицательных размеров и, таким образом, выводить лучшее сообщение об ошибке.Возможно, они считают, что это того не стоит, потому что, если вы это сделаете, это уже выдает сообщение об ошибке.

Как это бывает, на самом деле нехватка памяти трудна, потому что ОС будет очень стараться поддерживать процесс, такой какиспользуя виртуальную память.Ваша система остановится до того, как исчерпает память.Итак, я обнаружил, что большинство ошибок нехватки памяти вызвано запросами на отрицательные объемы памяти.Насколько я помню, единственные реальные ошибки нехватки памяти, которые я получил, были в Java, вероятно, из-за использования виртуальной машины.

8 голосов
/ 15 октября 2011

Оказывается, это не ошибка памяти. Как отметил Уинстон Эверт, я фактически вводил отрицательные параметры в метод изменения размера изображений.

Несмотря на то, что в документации по python говорится, что ошибки памяти связаны с проблемами с памятью, эта ошибка возникает, когда вы даете отрицательные параметры для изменения размера. Я подозреваю, что, поскольку PIL интенсивно использует библиотеки C, они могут привести к утечкам при неправильном вводе, и поскольку библиотека не выполняет проверку границ, ошибка просто всплывает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...