我有一个PHP脚本,用于调整用户FTP文件夹中的图像大小,以便在他的网站上使用。
虽然调整速度很慢,但脚本已经正确完成了过去的所有图像。然而,最近,用户上传了一张21百万像素JPEG图像的专辑,正如我所发现的,该脚本无法转换图像,但没有发出任何PHP错误。当我查阅各种日志时,我发现有多个Apache进程因内存不足错误而被终止。
PHP脚本的功能部分本质上是一个for循环,它遍历磁盘上的我的图像并调用一个检查缩略图是否存在的方法,然后执行以下操作:
$image = new Imagick();
$image->readImage($target);
$image->thumbnailImage(1000, 0);
$image->writeImage(realpath($basedir)."/".rescale."/".$filename);
$image->clear();
$image->destroy();
服务器有512MB的RAM,通常至少360MB +免费。
PHP的内存限制设置目前为96MB,但我之前设置的更高,但没有对此问题产生任何影响。
根据我的估计,在未压缩时,2100万像素的图像应该占据80MB +的区域,所以我很困惑为什么RAM会如此迅速地消失,除非Image Magick对象没有从内存中移除。
有什么方法可以优化我的脚本以更有效地使用更少的内存或垃圾收集? 我根本没有RAM来处理如此大的图像吗?
干杯
答案 0 :(得分:5)
有关更详细的说明,请参阅this answer。
imagick使用共享库并且它的内存使用对于PHP来说是遥不可及的,因此调整PHP内存和垃圾收集将无济于事。
尝试在创建new Imagick()
对象之前添加此对象:
// pixel cache max size
IMagick::setResourceLimit(imagick::RESOURCETYPE_MEMORY, 32);
// maximum amount of memory map to allocate for the pixel cache
IMagick::setResourceLimit(imagick::RESOURCETYPE_MAP, 32);
当需要超过32 MB的杂耍图像时,它会导致想象力交换到磁盘(默认为/ tmp)。它会慢一些,但它不会耗尽RAM(除非/ tmp在ramdisk上,在这种情况下你需要改变imagick写入临时文件的地方)。
答案 1 :(得分:4)
MattBianco几乎是正确的,唯一的变化是内存限制以字节为单位,因此对于32MB将是33554432:
// pixel cache max size
IMagick::setResourceLimit(imagick::RESOURCETYPE_MEMORY, 33554432);
// maximum amount of memory map to allocate for the pixel cache
IMagick::setResourceLimit(imagick::RESOURCETYPE_MAP, 33554432);
答案 2 :(得分:2)
在$image->setSize()
之前调用$image->readImage()
让libjpeg在加载时调整图像大小以减少内存使用量。
(编辑),示例用法:Efficient JPEG Image Resizing in PHP