1

我正在对最大 10MB 的文件使用单个图像上传/裁剪/调整大小脚本。

测试时,我将 php_ini 内存限制设置为 25M,上传文件仅约 1.4MB 时已耗尽。

"Allowed memory size of 26214400 bytes exhausted (tried to allocate 10368 bytes)"

这对我来说似乎很奇怪,不是 10368 < 26214400 吗?(反问)

或者这是否意味着我在 25MB 上占用了 10368 字节?我的脚本应该使用这么多内存吗?

代码:

function make_thumbnails($updir, $img)
{
    $thumbnail_width    = 200;
    $thumbnail_height   = 150;
    $thumb_preword  = "thumb_";

    $arr_image_details  = GetImageSize($updir.$img);
    $original_width = $arr_image_details[0];
    $original_height    = $arr_image_details[1];

    if( $original_width > $original_height ){
        $new_width  = $thumbnail_width;
        $new_height = intval($original_height*$new_width/$original_width);
    } else {
        $new_height = $thumbnail_height;
        $new_width  = intval($original_width*$new_height/$original_height);
    }

    $dest_x = intval(($thumbnail_width - $new_width) / 2);
    $dest_y = intval(($thumbnail_height - $new_height) / 2);

    if($arr_image_details[2]==1) { $imgt = "ImageGIF";  $imgcreatefrom = "ImageCreateFromGIF";  }
    if($arr_image_details[2]==2) { $imgt = "ImageJPEG"; $imgcreatefrom = "ImageCreateFromJPEG";  }
    if($arr_image_details[2]==3) { $imgt = "ImagePNG";  $imgcreatefrom = "ImageCreateFromPNG";  }

    if( $imgt )
    {
        $old_image = $imgcreatefrom($updir.$img);
        $new_image = imagecreatetruecolor($thumbnail_width, $thumbnail_height);
        imageCopyResized($new_image,$old_image,$dest_x,
        $dest_y,0,0,$new_width,$new_height,$original_width,$original_height);
        $imgt($new_image,$updir.$thumb_preword.$img);

        // Added by your suggestions:
         imagedestroy($old_image);
         imagedestroy($new_image);
    }
}
4

5 回答 5

14

除了已经说过的:

永远不要忘记处理压缩文件格式(如 JPEG)需要比实际文件大小更多的内存。一个 3000 x 3000 像素的 JPG 文件仅重 500kb,但需要(大约)3000 x 3000 x 3(红色、绿色和蓝色各一个字节,取决于模式,Alpha 甚至还要一个字节)= 至少 27 MB .

于 2009-11-14T18:24:16.623 回答
4

错误消息说它试图再分配 10368 个字节,但它不可用。换句话说,您的 25MB 池已用尽,脚本无法分配所需的 10368 字节。

您可以php.ini通过添加或更新类似于以下内容的行来增加文件中的此限制:

memory_limit = 64M

至于“如果 25MB 就足够了”,这对我们来说是一个难以回答的问题……当然有一些脚本合法地需要 64MB 甚至更多。如果您发现必须不断增加内存池的大小,我会开始调查是什么占用了这么多空间。

这是一个相关的问题,对内存池的大小进行了一些很好的讨论。

编辑看到您发布的代码,当您使用图像时,绝对有可能消耗大量内存。imagedestroy完成图像资源后,您可以通过调用来帮助您的脚本。

于 2009-11-14T18:13:45.583 回答
2

或者这是否意味着我在 25MB 上占用了 10368 字节?

不,您的脚本试图分配 10368 字节,10368 + 已分配 > 25MB

我的脚本应该使用这么多内存吗?

如果您使用 GD 调整大小,是的。我会尝试使用其他库或控制台工具进行图像处理,它们可以提供更多性能。而且,如果它是公共网站,您可以决定使用队列进行图像处理而不是及时调整图像大小

于 2009-11-14T18:18:55.483 回答
2

使用imagedestroy后释放内存:

if( $imgt )
{
    $old_image = $imgcreatefrom($updir.$img);
    $new_image = imagecreatetruecolor($thumbnail_width, $thumbnail_height);
    imageCopyResized($new_image,$old_image,$dest_x,
    $dest_y,0,0,$new_width,$new_height,$original_width,$original_height);
    imagedestroy($old_image);
    $imgt($new_image,$updir.$thumb_preword.$img);
    imagedestroy($new_image);
}
于 2009-11-14T18:20:50.313 回答
1

这意味着在您超出限制的那一刻,您的脚本正在尝试分配 10368 字节,但没有成功。这并不意味着如果您将限制增加到 26MB,您将不再遇到此问题。该错误可能会在稍后发生。您可能会尝试以较小的步长(例如 32MB、48MB 等)增加它,直到不再出现此错误。

于 2009-11-14T18:14:19.937 回答