I have to render something with Imagick on PHP CLI.
I have noticed that every 3-5 days the server memory gets full, so i can’t even connet via ssh or ftp.
with memory_get_usage() i narrwoed the memory leak down to the imagick part of the script.
the script looks something like this:
$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);
I destroy the image reference, and unset the imagick and imagickDraw object, but the script won’t release any memory.
The setFillColor() method takes the most memory
Can i do something else to free the space used by imageick?
imagick uses a shared library and it’s memory usage is out of reach for PHP, so tuning PHP memory and garbage collection won’t help.
I had the same problem myself, trying to handle a multi-page-tiff image with 50 (!) pages of 3000×2000 pixels.
The solution is to have imagick put its pixel cache on disk.
Adding this prior to creating the
Imagickobject solved the problem for me:The goal is to make imagick put its pixel cache on disk instead of in RAM. The default place seems to be files /tmp/magick-XXnnnnn, so make sure /tmp is not on shmfs/ramdisk, or change the temp directory imagick uses.
Other resouce limits to investigate:
imagick::RESOURCETYPE_DISK,imagick::RESOURCETYPE_FILE, andimagick::RESOURCETYPE_AREA.They are described in the imagick::getResourceLimit() manual page (not so well in the page for
setResourceLimit()).In my image handling loop, I have
set_time_limit(300), since the script takes ages to process this huge (when uncompress) image.EDIT : In recent versions,
setResourceLimit()should not be called as a static method, but on the actual object instead, such as: