我必须在PHP CLI上使用Imagick渲染某些东西。
我注意到服务器内存每3-5天满一次,所以我什至无法通过ssh或ftp连接。

我使用memory_get_usage()将内存泄漏归结为脚本的imagick部分。
脚本看起来像这样:

$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);

我销毁图像引用,并取消设置imagick和imagickDraw对象,但是脚本不会释放任何内存。
setFillColor()方法占用最多的内存

我可以做些其他事情来释放imageick占用的空间吗?

image of the memory consumption

最佳答案

imagick使用一个共享库,它的内存使用情况对于PHP来说是遥不可及的,因此调优PHP内存和垃圾回收将无济于事。

我本人也遇到了同样的问题,试图处理50(!)页3000x2000像素的多页tiff图像。
解决方案是让imagick将其像素缓存放在磁盘上。

在创建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将其像素缓存放置在磁盘上,而不是在RAM中。默认位置似乎是文件/tmp/magick-XXnnnnn,因此请确保/tmp不在shmfs/ramdisk上,或者更改imagick使用的临时目录。

要调查的其他资源限制:imagick::RESOURCETYPE_DISKimagick::RESOURCETYPE_FILEimagick::RESOURCETYPE_AREA
它们在imagick::getResourceLimit() manual page中进行了描述(在setResourceLimit()的页面中不是很好)。

在我的图像处理循环中,我有set_time_limit(300),因为脚本需要花费很多时间来处理这个巨大的图像(在解压缩时)。

编辑:在最新版本中,不应将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);

关于PHP Imagick内存泄漏,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9993085/

10-13 00:06