Ограничение памяти PHP 25 МБ исчерпано - загрузка файла / обрезка / изменение размера - PullRequest
1 голос
/ 14 ноября 2009

Я использую один скрипт загрузки / обрезки / изменения размера изображения для файлов размером до 10 МБ.

При тестировании я установил предел памяти php_ini 25 МБ, и он исчерпан при загрузке файла только около 1,4 МБ.

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

Мне кажется это странным, не правда ли 10368 <26214400? (Риторический вопрос) </p>

Или это означает, что я перешел 10368 байт за 25 МБ? Должен ли мой сценарий использовать столько памяти?

Код:

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);
    }
}

Ответы [ 5 ]

14 голосов
/ 14 ноября 2009

В дополнение к тому, что уже было сказано:

Никогда не забывайте, что обработка форматов сжатых файлов (например, JPEG) требует гораздо больше памяти, чем фактический размер файла. Файл JPG размером 3000 x 3000 пикселей может весить всего 500 КБ, но для этого потребуется (примерно) 3000 x 3000 x 3 (один байт для красного, зеленого и синего, а в зависимости от режима еще один для альфы) = не менее 27 МБ .

4 голосов
/ 14 ноября 2009

В сообщении об ошибке говорится, что он попытался выделить еще 10368 байт, но он не был доступен. Другими словами, ваш пул в 25 МБ исчерпан, и сценарий не может выделить 10368 байт, которые ему нужны.

Вы можете увеличить это ограничение в файле php.ini, добавив или обновив строку, подобную следующей:

memory_limit = 64M

Насколько "достаточно 25 МБ", нам сложно ответить на этот вопрос ... Есть, конечно, некоторые сценарии, которым по праву требуется 64 МБ или даже больше. Если вы обнаружите, что вам нужно постоянно увеличивать размер пула памяти, я бы начал изучать, что занимает так много места.

Вот связанный вопрос , в котором хорошо обсуждается размер пула памяти.

РЕДАКТИРОВАТЬ Увидев опубликованный код, можно определенно использовать большой объем памяти при работе с изображениями. Вы можете помочь вашему сценарию, позвонив imagedestroy после того, как вы закончили с ресурсом изображения.

2 голосов
/ 14 ноября 2009

Используйте 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);
}
2 голосов
/ 14 ноября 2009

Или это означает, что я перешел на 10368 байт за 25 МБ?

Нет. Ваш скрипт пытался выделить 10368 байт, 10368 + alreadyallocated> 25MB

Должен ли мой скрипт использовать столько памяти?

Если вы используете GD для изменения размера, да. Я бы попробовал использовать другие библиотеки или консольные инструменты для обработки изображений, они могут дать большую производительность. И вы можете решить использовать очередь для обработки изображений, а не изменять размер изображений точно в срок, если это общедоступный веб-сайт

1 голос
/ 14 ноября 2009

Это означает, что в момент, когда вы превысили лимит, ваш скрипт пытался выделить 10368 байт, но это не удалось Это не значит, что у вас больше не возникнет этой проблемы, если вы увеличите лимит до 26 МБ. Ошибка может произойти на более позднем этапе. Вы можете попытаться увеличить его небольшими шагами (например, 32 МБ, 48 МБ и т. Д.), Пока не получите эту ошибку.

...