PHP memory_get_peak_usage и ini_set('memory_limit', '-1')

Недавно я столкнулся с проблемами выделения памяти, поэтому я начал экспериментировать с ini_set('memory_limit', value); Директива, где я пытался вводить значения постепенно. Теперь, просматривая в Интернете (и так), я обнаружил, что я могу поставить -1 как value, Итак, я сделал, и теперь сценарий выполняется полностью до конца, не прерываясь (раньше я использовал, чтобы получить ошибку выделения памяти).

Что я не понимаю, однако, это то, что с учетом этих двух строк в конце файла сценария:

$mem = memory_get_peak_usage(true);         
echo "Peak mem. usage: <b>" . round($mem / 1024 / 10124, 2) . "</b> MB";

производить около 10,8 МБ, и когда я смотрю в /var/log/messages Я вижу эту строку:

Nov 21 13:52:26 mail suhosin[1153]: ALERT-SIMULATION - script tried to increase  
memory_limit to 4294967295 bytes which is above the allowed value (attacker  
'xx.xxx.xxx.xxx', file '/var/www/html/file.php', line 5)

что означает, что скрипт пытался выделить 4096MB!

Как это может быть? А также, что меня больше всего интересует, почему выполнение сценария не остановилось в этом случае? Это из-за ini_set('memory_limit', '-1');? Я имею в виду, я читал, что положить -1 как value не рекомендуется, и я знаю, в чем заключается проблема в скрипте (считывание слишком большого количества данных сразу в память), и я пойду и исправлю это с последовательным чтением, но я просто сбит с толку этими различиями данных, поэтому Я был бы благодарен, если бы кто-то мог пролить свет на это.

6 ответов

Решение

Это потому, что патч suhosin использует свой собственный "жесткий" максимальный предел памяти, suhosin.memory_limit,

Из ссылки на конфигурацию:

Сухосин не [...] запрещает устанавливать memory_limit до значения, превышающего то, с которого скрипт начинал, когда эта опция оставлена ​​равной 0.

Другими словами, если вы измените memory_limit так что он больше верхнего предела suhosin, тогда он просто будет считать, что вы "атакующий", пытаясь сделать что-то подозрительное.

memory_get_peak_usage - возвращает пик памяти, выделенный PHP.

memory_limit - увеличить максимальное выделение памяти

<?php 
if(ini_set('memory_limit', '-1'))
{
    echo "memory_limit set to -1B";
}
else
{
    echo "ini_set() failed!"
}
?>

Думаю, что вы использовали 10 МБ, но, поставив -1 как value вы позволили вашему скрипту использовать максимально доступную память, скажем 4GB,

С помощью ini_set('memory_limit', '-1'); не будет устанавливать ограничение для сценариев - конечно, оно будет по-прежнему ограничено аппаратным обеспечением, но из руководства;

Обратите внимание, что для ограничения памяти, установите эту директиву -1

Что меня больше всего интересует, так это почему выполнение сценария не остановилось в этом случае?

Сценарий не остановил выполнение, потому что он не достиг максимального ограничения памяти, так как он установлен на -1,

Как описано здесь: http://www.hardened-php.net/suhosin/configuration.html

Suhosin не позволит вам установить значение больше, чем то, с которого начинался скрипт.

Если вы установите suhosin.memory_limit равным 4096, вы сможете увеличить использование памяти, не получая этого оповещения.

Я предполагаю, что скрипт не пытался выделить 4096 МБ, но это неверное предупреждение shuosin, показывающее максимальный предел адресуемой памяти 32-битной системы, на которой работает php-сервер, равный 2^32

Надеюсь, что это ответит на ваши сомнения

$mem / 1024 / 10124

должно быть

$mem / 1024 / 1024

Итак, мы говорим о пике в 100 МБ.

затем 4,294,967,295 = 4 GB, Я думаю, это все, что у вас есть (т.е. -1).

Это означает, что эти выходные сообщения не имеют ничего общего друг с другом. Если вы хотите, чтобы предупреждение исчезло, установите предел памяти Suhosin выше предела памяти PHP или отключите Suhosin.

Suhosin имеет режим симуляции, который, кажется, ON, Если это повернуто OFFПРЕДУПРЕЖДЕНИЕ должно остановить сценарий.

Другие вопросы по тегам