Я должен сделать что-то с 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);
эти решения работают более гладко, чем воображаемый. но мне не нравится код, подверженный ошибкам.