Форум dkLab и Denwer
Здесь общаются Web-разработчики.
Генеральный спонсор:
Хостинг «Джино»

Обработка нехватки памяти в скрипте backend'а (Fog)
Author Message
Fog
Участник форума



Joined: 23 Mar 2003
Posts: 31
Карма: 0
   поощрить/наказать


PostPosted: Thu Jul 26, 2007 11:31 am (написано за 2 минуты 59 секунд)
   Post subject: Обработка нехватки памяти в скрипте backend'а
Reply with quote

Столкнулся с такой проблемой: загружаю изображение посредством JsHttpRequest, там оно ресайзается и сохраняется.

Для обработки некоторых файлов нехватает памяти, и в таком случае работа скрипта просто прерывается, JS фнкция, которая должна срабатывать при получении ответа так же не отрабатывает.

Есть ли способ как-то обработать этот момент, и сообщить пользователю, что загрузка файла прошла неудачно?
Back to top
View user's profile Send private message
Юрий Насретдинов
Модератор



Joined: 13 Mar 2003
Posts: 8642
Карма: 198
   поощрить/наказать

Location: 007 495

PostPosted: Thu Jul 26, 2007 2:13 pm (спустя 2 часа 42 минуты; написано за 1 минуту 28 секунд)
   Post subject:
Reply with quote

Fog
Вот тут: Функция для создания уменьшенной копии изображения (forum.dklab.ru/php/advises/FunctionForCreationOfTheReducedCopyOfTheImage.html) реализована защита от подобного. Правда, она иногда всё же даёт сбой, но довольно редко.

Каких-либо способов перехватить ошибку нехватки памяти на PHP4.3 я не обнаружил, поэтому решение, которое представлено по ссылке, ИМХО, единственное более-менее рабочее.
Back to top
View user's profile Send private message Send e-mail
Fog
Участник форума



Joined: 23 Mar 2003
Posts: 31
Карма: 0
   поощрить/наказать


PostPosted: Thu Jul 26, 2007 2:33 pm (спустя 19 минут; написано за 12 секунд)
   Post subject:
Reply with quote

Юрий, спасибо! Буду читать.
Back to top
View user's profile Send private message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Thu Aug 02, 2007 9:00 pm (спустя 7 дней 6 часов 27 минут; написано за 2 минуты 55 секунд)
   Post subject:
Reply with quote

Да, с ошибкой нехватки памяти беда.

Правда, я подозреваю, что в идеале JsHttpRequest все-таки должен ее перехватывать штатным способом, т.к. ob-хэндлер вызывается даже для фатальных ошибок. Однако я заметил уже давно, что иногда он не вызывается. Подозреваю, это из-за того, что ему самому не хватает памяти для вызова, и он генерит ошибку вторично! Поэтому можно попробовать такой вариант: где-нибудь в скрипте выделить 100К памяти (строковую переменную) и держать ее присвоенной. А в первой строчке ob-процессора - эту переменную освобождать (просто делать unset для нее). В итоге высвободится 100К памяти, которой должно хватить.

Правда, это все лишь теория. На практике я эти рассуждения не проверял! Но у Вас есть реальная возможность их проверить.
Back to top
View user's profile Send private message Send e-mail
Юрий Насретдинов
Модератор



Joined: 13 Mar 2003
Posts: 8642
Карма: 198
   поощрить/наказать

Location: 007 495

PostPosted: Thu Aug 02, 2007 9:13 pm (спустя 12 минут; написано за 1 минуту 7 секунд)
   Post subject:
Reply with quote

Дмитрий Котеров
Идея интересная... Вот только хватит ли 100 кб твоему обработчику?

В любом случае, я попробовал на PeterHost следующий код:
Code (php): скопировать код в буфер обмена
<?
ob_start (www.php.net/ob_start)('callback');

function callback($buf)
{
unset (www.php.net/unset)($GLOBALS['firebuf']);

return $buf.' -- added Hello :)';
}

/* echo memory_get_usage(); */

$firebuf = str_repeat (www.php.net/str_repeat)('a', 1024000);

while(1) $tmp[] = $firebuf;
?>
И он выдаёт Bad Gateway -- dolphin.msk.su/files/memory_limit.php
Back to top
View user's profile Send private message Send e-mail
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Sat Aug 04, 2007 2:44 pm (спустя 1 день 17 часов 30 минут; написано за 33 секунды)
   Post subject:
Reply with quote

Bad Gateway выдает nginx, а не апач. Мало ли, почему.
А что в логах сервера? Написано про memory limit?
Back to top
View user's profile Send private message Send e-mail
Юрий Насретдинов
Модератор



Joined: 13 Mar 2003
Posts: 8642
Карма: 198
   поощрить/наказать

Location: 007 495

PostPosted: Sat Aug 04, 2007 3:31 pm (спустя 47 минут; написано за 1 минуту 33 секунды)
   Post subject:
Reply with quote

Дмитрий Котеров
Code (any language): скопировать код в буфер обмена
[Sat Aug  4 16:29:15 2007] [error] PHP Fatal error:  Allowed memory size of 16777216 bytes exhausted (tried to allocate 71 bytes) in .../files/memory_limit.php on line 15
На 15 строчке именно $tmp[]=$firebuf;
Дмитрий Котеров wrote:
Bad Gateway выдает nginx, а не апач.
Я разве говорил, что Apache выдаёт этот ответ :)? Суть в том, что ошибку перехватить не получается.

А следующий код:
Code (php): скопировать код в буфер обмена
<?
ob_start (www.php.net/ob_start)('callback');

function callback($buf)
{
unset (www.php.net/unset)($GLOBALS['firebuf']);

return $buf.' -- added Hello :)';
}

function report_error()
{
$f = fopen (www.php.net/fopen)("works","w");
fclose (www.php.net/fclose)($f);
}

register_shutdown_function (www.php.net/register_shutdown_function)('report_error');
/* echo memory_get_usage(); */

$firebuf = str_repeat (www.php.net/str_repeat)('a', 1024000);

while(1) $tmp[] = $firebuf;
?>
Не только ничего не пишет в браузер, но и не создаёт файл "works", хотя и должен бы...
Back to top
View user's profile Send private message Send e-mail
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Sat Aug 04, 2007 9:53 pm (спустя 6 часов 21 минуту; написано за 2 минуты 37 секунд)
   Post subject:
Reply with quote

shutdown_function не вызываются при фатальных ошибках.
Ну, значит, не работает такой способ с резервированием буфера.

Хотя, на самом деле, у тебя в коде ошибка: оператор $tmp[] = $firebuf; в действительности не 1М памяти забирает, а всего несколько байт (т.к. переменные в PHP копируются отложенно). Поэтому, возможно, у него не хватает памяти даже для того, чтобы выделить в стеке буфер для вызова ob-обработчика. Попробуй честно сделать $tmp[] = str_repeat('x', 1024 * 10), чтобы память пачками занималась.

Какая версия PHP?
Back to top
View user's profile Send private message Send e-mail
Юрий Насретдинов
Модератор



Joined: 13 Mar 2003
Posts: 8642
Карма: 198
   поощрить/наказать

Location: 007 495

PostPosted: Sat Aug 04, 2007 11:08 pm (спустя 1 час 15 минут; написано за 1 минуту 41 секунду)
   Post subject:
Reply with quote

Дмитрий Котеров wrote:
$tmp[] = $firebuf; в действительности не 1М памяти забирает, а всего несколько байт (т.к. переменные в PHP копируются отложенно).
Блин, а ведь действительно... Если почитать текст ошибки, то там видно, что он по 71 байту выделяет...
Code (php): скопировать код в буфер обмена
<?
ini_set (www.php.net/ini_set)('display_errors', 'On');
ob_start (www.php.net/ob_start)('callback');

function callback($buf)
{
unset (www.php.net/unset)($GLOBALS['firebuf']);

$muchmem = str_repeat (www.php.net/str_repeat)('a', 102400);

return $buf.' -- added Hello :)';
}

/* echo memory_get_usage(); */

$firebuf = str_repeat (www.php.net/str_repeat)('a', 1024000);

while(1) $tmp[] = str_repeat (www.php.net/str_repeat)('a', 10240);
?>
( dolphin.msk.su/files/memory_limit.php )

Рвботает на ура! Я теперь понял, почему у меня не получалось эту ошибку отловить.

PHP версии 4.4.4
Back to top
View user's profile Send private message Send e-mail
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Sun Aug 05, 2007 12:07 am (спустя 58 минут; написано за 1 минуту 40 секунд)
   Post subject:
Reply with quote

Обалдеть. Я ведь просто угадал метод, даже в исходники не смотря.

Что же, можно сделать патч для JsHttpRequest тогда. Вот только хватит 100К или нет - этого заранее нельзя предсказать, все зависит от размера выходного потока. Но вероятность того, что библиотека эту ошибку все-таки перехватит, сильно возрастает (хотя и не до 100%).
Back to top
View user's profile Send private message Send e-mail
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Sun Aug 05, 2007 12:51 am (спустя 44 минуты; написано за 45 секунд)
   Post subject:
Reply with quote

Кстати, отличная тема для наблы, вот: dklab.ru/chicken/nablas/45.html
Добавил патч в JsHttpRequest. Добавил также тест для него.

К автору топика: попробуйте новую версию JsHttpRequest. Перехватывает ли она ошибку нехватки памяти?
Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic   Reply to topic All times are GMT + 3 Hours
Page 1 of 1    Email to a Friend.
Post a reply
Username
Subject
Господа спамеры и оптимизаторы!

Вы можете даже и не пытаться вставлять в текст поста ссылки - они все равно автоматически удаляются (вернее, тэги <a> заменяются на тэги <u>).

Но если не поверите и все же попытаетесь - как только увидите, что все безрезультатно, удалите свой пост, пожалуйста. Модераторы тоже люди, нехорошо, если они погрязнут в тоннах спама.
     

Disable BBCode in this post
Disable Smilies in this post
    HTML is OFF
BBCode is ON
Smilies are ON
You cannot post new topics in this forum. You can reply to topics in this forum. You cannot edit your posts in this forum. You cannot delete your posts in this forum. You cannot vote in polls in this forum. You cannot attach files in this forum. You can download files in this forum.
XML