【问题标题】:PHP GD Allowed memory size exhaustedPHP GD 允许的内存大小已用尽
【发布时间】: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 设置。这似乎是一个糟糕的解决方法,可能会在未来导致更多问题。

仅供参考:我正在从命令提示符运行我的脚本。它不应该影响功能,但可能会影响您的反应,所以我想我应该提一下。

谁能看看我是否只是遗漏了一些简单的东西,或者这里是否存在设计缺陷?你会认为这将是一项非常简单的任务。这肯定是可能的,对吧?

【问题讨论】:

    标签: php gd


    【解决方案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 设置为您想要的任何大小。

      【讨论】:

        猜你喜欢
        • 2013-02-08
        • 2020-04-10
        • 2015-10-13
        • 2017-08-26
        • 2023-03-31
        • 2014-09-05
        • 2012-04-30
        • 1970-01-01
        • 2015-11-30
        相关资源
        最近更新 更多