PHP не может использовать 300 МБ оперативной памяти
Я пытаюсь увеличить разрешенную память для определенного сценария PHP. Независимо от того, что я делаю, например это:
ini_set('memory_limit', '512M');
... сценарию всегда не хватает памяти около 300 МБ:
Fatal error: Out of memory (allocated 25165824) (tried to allocate 343810589 bytes) in \\Foo\phpQuery\phpQuery.php on line 255
Я подтвердил несколькими способами, что memory_limit
на самом деле изменилось. Кажется, проблема в том, что PHP не может физически выделить 300 МБ памяти (25165824 байт + 343810589 байт = 352 МБ).
Я пробовал оба PHP/5.3.0 и PHP/5.3.9 на двух разных компьютерах под управлением Windows со следующими характеристиками:
- Windows XP / Windows Server 2003 (оба компьютера имеют 32-битные блоки с 1 ГБ или ОЗУ)
- Официальные PHP 32-битные двоичные файлы VC9
- Работает как модуль Apache 2.2 (сторонние 32-битные двоичные файлы VC9)
Я понимаю, что использование половины физической оперативной памяти приведет к принудительной подкачке и замедлению работы, но мне просто нужно убедиться, что скрипт действительно работает, чтобы его можно было развернуть на работающем сервере. Я также пробовал большие значения (которые вызывали ту же ошибку) и меньшие значения (либо заставил мой скрипт достигнуть предела, либо произвел сбой Apache).
Что может быть источником этого явно жестко ограниченного объема памяти?
Обновление № 1: я провел дальнейшее тестирование с помощью Windows Server 2003 (на самом деле это виртуальная машина VMWare). Я увеличил "физическую" оперативную память до 2 ГБ и убедился, что файлу подкачки разрешено увеличиваться до 1152 МБ. Диспетчер задач показывает, что текущая нагрузка транзакции составляет 886 МБ, а свободной физической памяти 1,5 ГБ. Тем не менее, я получаю ту же ошибку с точно такими же цифрами.
Обновление № 2: Как я уже сказал, memory_limit
Директива в порядке. Это проявляется в обоих ini_get()
а также phpinfo()
, Сообщение об ошибке, которое вы получите, немного отличается от моего; мой указывает на сбой PHP. Пожалуйста, сравните:
Out of memory (allocated 25165824) (tried to allocate 343810589 bytes)
Allowed memory size of 25165824 bytes exhausted (tried to allocate 343810589 bytes)
Я постараюсь составить сценарий, чтобы воспроизвести проблему и доложить.
2 ответа
Исключение OOM отличается от предупреждений об ограничении памяти.
Это означает, что PHP не может на самом деле выделить память, потому что в вашей операционной системе недостаточно ресурсов.
Вам необходимо убедиться, что в системе достаточно памяти / подкачки для поддержки этого.
Попробуйте с max_input_time, иногда, когда PHP говорит memory_limit, это на самом деле означает max_input_time (-1 для этого бесконечно).
У меня была аналогичная проблема с ошибками нехватки памяти, появляющимися при цифрах от 250 МБ. Если вы найдете свой файл конфигурации apache, который управляет ThreadsPerChild (для меня это был /conf/extra/httpd-mpm.conf) и уменьшите ThreadsPerChild со 150 до 50 или около того, вы должны увидеть заметное улучшение... вот сценарий для проверить это:
echo "Memory limit: ".ini_get("memory_limit")."<br><br>";
$a=array();
if (ob_get_level() == 0) ob_start();
for($i=0;$i<200;$i++)
{
$a[]=str_pad('',1024*1024*32);
echo "Pass ".$i.", memory used: ".number_format((memory_get_usage())/(1024*1024),0)." MB<br>";
ob_flush();
flush();
}