Утечка памяти PHP Imagick

Я должен сделать что-то с Imagick на PHP CLI. Я заметил, что каждые 3-5 дней память сервера заполняется, поэтому я даже не могу подключиться через ssh или ftp.

с memory_get_usage () я описал утечку памяти к воображаемой части скрипта. сценарий выглядит примерно так:

$sourceImg = 'source.png'; $destImg = 'dest.png'; $background ='#00ff00'; $im = new Imagick(); $im->pingImage($sourceImg); $im->readImage($sourceImg); $draw = new ImagickDraw(); for($i=1;$i<=5;$i++){ $draw->setFillColor( $background); $draw->rectangle( 10*$i+5, 10, 10*$i+10, 20); } $im->drawImage( $draw ); $im->writeImage( $destImg ); $im->destroy(); unset($im,$draw); 

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

Могу ли я сделать что-то еще, чтобы освободить пространство, используемое imageick?

изображение потребления памяти

imagick использует общую библиотеку, и использование ее памяти недостижимо для PHP, поэтому настройка памяти PHP и сборка мусора не поможет.

У меня была такая же проблема, пытаясь обработать многостраничное изображение с 50 (!) Страницами размером 3000х2000 пикселей. Решение состоит в том, чтобы вообразить свой кеш пикселя на диске.

Добавление этого до создания объекта Imagick решило проблему для меня:

 // pixel cache max size IMagick::setResourceLimit(imagick::RESOURCETYPE_MEMORY, 256); // maximum amount of memory map to allocate for the pixel cache IMagick::setResourceLimit(imagick::RESOURCETYPE_MAP, 256); 

Цель состоит в том, чтобы заставить imagick поместить свой пиксельный кеш на диск, а не в ОЗУ. По умолчанию используется файл / tmp / magick-XXnnnnn, поэтому убедитесь, что / tmp не находится на shmfs / ramdisk, или измените каталог temp, используемый пользователем.

Другие ограничения для исследования: imagick::RESOURCETYPE_DISK , imagick::RESOURCETYPE_FILE и imagick::RESOURCETYPE_AREA . Они описаны на странице руководства imagick :: getResourceLimit () (не так хорошо на странице setResourceLimit() ).

В моем цикле обработки изображений у меня есть set_time_limit(300) , так как сценарий занимает много времени, чтобы обработать это огромное (при несжатом) изображении.


EDIT: В последних версиях setResourceLimit() не следует вызывать как статический метод, а вместо этого вместо фактического объекта:

 $im->setResourceLimit(imagick::RESOURCETYPE_MEMORY, 256); $im->setResourceLimit(imagick::RESOURCETYPE_MAP, 256); $im->setResourceLimit(imagick::RESOURCETYPE_AREA, 1512); $im->setResourceLimit(imagick::RESOURCETYPE_FILE, 768); $im->setResourceLimit(imagick::RESOURCETYPE_DISK, -1); 

Я знаю, что это старо, но я столкнулся с той же проблемой и назвал $im->clear() вместо $im->destroy() исправил утечку памяти для меня.

Согласно документации Imagick::destroy() has been deprecated in favor of Imagick::clear() . Поэтому следует использовать clear() .

xdebug не смог мне помочь .. поэтому я решил посмотреть на другое решение. Я придумал использовать обратную магию:

 $sourceImg = 'source.png'; $destImg = 'dest.png'; $background ='#00ff00'; $command = "convert {$sourceImg}"; $out = array(); for($i=1;$i<=5;$i++){ $command .= " -fill \"{$background}\" "; $command .= " -draw 'rectangle {$x1},{$y1} {$x2},{$y2}'"; } $command .= " {$destImg}"; exec($command,$out); 

эти решения работают более гладко, чем воображаемый. но мне не нравится код, подверженный ошибкам.