PHP Imagick 内存泄漏
我必须在 PHP CLI 上用 Imagick 渲染一些东西.我注意到每 3-5 天服务器内存就会满,所以我什至无法通过 ssh 或 ftp 连接.
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.
使用 memory_get_usage() 我将内存泄漏缩小到脚本的 imagick 部分.脚本看起来像这样:
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);
我销毁了图像引用,并取消了 imagick 和 imagickDraw 对象的设置,但脚本不会释放任何内存.setFillColor() 方法占用的内存最多
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
我可以做些什么来释放 imageick 使用的空间吗?
Can i do something else to free the space used by imageick?
内存消耗图片
推荐答案
imagick 使用共享库,它的内存使用量对于 PHP 来说是遥不可及的,因此调整 PHP 内存和垃圾收集无济于事.
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.
我自己也遇到了同样的问题,试图处理 50 (!) 页 3000x2000 像素的多页 tiff 图像.解决方案是让 imagick 将其像素缓存放在磁盘上.
I had the same problem myself, trying to handle a multi-page-tiff image with 50 (!) pages of 3000x2000 pixels. The solution is to have imagick put its pixel cache on disk.
在创建 Imagick
对象之前添加它为我解决了这个问题:
Adding this prior to creating the Imagick
object solved the problem for me:
// 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 使用的临时目录.
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.
要调查的其他资源限制:imagick::RESOURCETYPE_DISK
、imagick::RESOURCETYPE_FILE
和 imagick::RESOURCETYPE_AREA
.它们在 imagick::getResourceLimit() 手册页中有描述(在页面中不太好)对于 setResourceLimit()
).
Other resouce limits to investigate: imagick::RESOURCETYPE_DISK
, imagick::RESOURCETYPE_FILE
, and imagick::RESOURCETYPE_AREA
.
They are described in the imagick::getResourceLimit() manual page (not so well in the page for setResourceLimit()
).
在我的图像处理循环中,我有 set_time_limit(300)
,因为脚本需要很长时间来处理这个巨大的(解压缩时)图像.
In my image handling loop, I have set_time_limit(300)
, since the script takes ages to process this huge (when uncompress) image.
EDIT : 在最近的版本中,
setResourceLimit()
不应作为静态方法调用,而是在实际对象上调用,例如:>
EDIT : In recent versions,
setResourceLimit()
should not be called as a static method, but on the actual object instead, such as:
$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);
相关文章