PHP GD 允许的内存大小已用尽
Posted
技术标签:
【中文标题】PHP GD 允许的内存大小已用尽【英文标题】:PHP GD Allowed memory size exhausted 【发布时间】:2010-05-13 15:14:54 【问题描述】:我正在尝试使用 php: GD 来处理 JPEG 图像的目录(大约 600+,范围从 50k 到 500k)来调整大小并保存图像,但我在此过程的早期遇到了一些障碍.仅正确处理 3 张图像(30K、18K 和 231K)后,我得到 Allowed memory size of 16777216 bytes exhausted PHP 致命错误。
我正在浏览图片并调用以下代码:
list($w, $h) = getimagesize($src);
if ($w > $it->width)
$newwidth = $it->width;
$newheight = round(($newwidth * $h) / $w);
elseif ($w > $it->height)
$newheight = $it->height;
$newwidth = round(($newheight * $w) / $h);
else
$newwidth = $w;
$newheight = $h;
// create resize image
$img = imagecreatetruecolor($newwidth, $newheight);
$org = imagecreatefromjpeg($src);
// Resize
imagecopyresized($img, $org, 0, 0, 0, 0, $newwidth, $newheight, $w, $h);
imagedestroy($org);
imagejpeg($img, $dest);
// Free up memory
imagedestroy($img);
我尝试使用imagedestroy
函数释放内存,但似乎没有任何影响。该脚本总是在imagecreatefromjpeg
代码行中一直阻塞。
我检查了 php.ini 并且 memory_limit = 16M
设置似乎保持正确。但我无法弄清楚为什么内存会被填满。它不应该将内存释放回垃圾收集器吗?我真的不想增加 memory_limit 设置。这似乎是一个糟糕的解决方法,可能会在未来导致更多问题。
仅供参考:我正在从命令提示符运行我的脚本。它不应该影响功能,但可能会影响您的反应,所以我想我应该提一下。
谁能看看我是否只是遗漏了一些简单的东西,或者这里是否存在设计缺陷?你会认为这将是一项非常简单的任务。这肯定是可能的,对吧?
【问题讨论】:
【参考方案1】:ini_set('memory_limit', '64M');
问题解决了
【讨论】:
我会试试这个。我的猜测是它会在这个过程的后期出错。我希望我错了。 我想我应该只发布要做什么而不是为什么要这样做。 我听到了。您的回答很有帮助,但这是解决方案。谢谢您的帮助。没有难过的感觉。 很好奇,php页面加载后内存是否会清理干净,还是全部存储在某个永久队列中并累积到服务器崩溃? @ina - 此命令允许此用户执行最多 64MB。请记住,实际内存使用量(希望)更少,并且在 PHP 为该页面运行完成的那一刻就被刷新了。【参考方案2】:有可能您的一张或多张图片在原始内存中实际膨胀到 16M。一种检查方法是在 Photoshop 或 Irfanview 中打开它并检查色彩空间和像素尺寸。
达到 16M 并不需要太多,例如,考虑一个“低”的 6 兆像素相机。它创建一个 3072 x 2048 像素的图像。每个颜色一个字节 (RGB) 的原始大小是:
3072 x 2048 x 3 = 18,874,368
因此,您可能希望根据您希望处理的最大图像来增加内存。但你必须考虑它们的原始大小。
【讨论】:
而 gd 不仅存储三个字节,而且每个像素存储四个字节 ~ 25M 等一下。您是说 gd 将所有图像文件存储在内存中,即使它们已被销毁?这将使大规模处理像我这样的一组图像几乎是不可能的。 gd 不应该在销毁时释放内存吗? 不,它只是将压缩的 JPG 膨胀到原始内存大小以进行操作。当您销毁它时,它会释放内存。您只需要足够的空间来处理原始大小的图像。 显然这是一个 memory_limit 问题。我不知道我可以在脚本级别设置 memory_limit。【参考方案3】:在某些情况下,您根本无法预料要处理的图像所需的最高内存分配。为防止崩溃,您可以在循环前后添加以下命令:
register_shutdown_function ('my_function');
$mem_limit = ini_get ('memory_limit');
ini_set ('display_errors', false);
ini_set ('memory_limit', '400M'); // some high value
(...你的过程...)
ini_set ('memory_limit',$mem_limit);
并在函数“my_function()”中放置处理崩溃的代码。
【讨论】:
【参考方案4】:只需使用 ini_set();
并将 memory_limit 设置为您想要的任何大小。
【讨论】:
以上是关于PHP GD 允许的内存大小已用尽的主要内容,如果未能解决你的问题,请参考以下文章
php - 致命错误:允许的内存大小为 134217728 字节已用尽 [重复]