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 字节已用尽 [重复]

Composer 要求内存不足。 PHP致命错误:允许的内存大小为1610612736字节已用尽

诊断内存泄漏 - # 字节的允许内存大小已用尽

致命错误:允许的内存大小已用尽

PHP致命错误:允许的内存大小为2097152字节已用尽

允许的内存大小已用尽