Ошибка PHP из памяти, хотя memory_limit не достигнут
Я только что унаследовал сайт с PHP script, который постоянно исчерпывает память при 117 МБ. Это происходит даже тогда, когда я увеличиваю переменную PHP memory_limit до 312 МБ, что я делаю через php.ini.
Это теперь решено благодаря отличной подсказке от pcguru. См. Мой ответ ниже, который начинается: я наконец нашел ответ
ini_get('memory_limit')
возвращает значение, установленное в php.ini, поэтому я уверен, что Apache перезапустился после изменения значения. Я использую memory_get_usage(true)
, чтобы вернуть память, потребляемую script в разных точках на этом пути. И он постоянно терпит неудачу, когда он достигает 117 МБ.
Есть ли какой-то внутренний предел PHP, о котором я не знаю, он никогда не выделяет более 117 МБ для отдельного script?
Сервер имеет 1 ГБ ОЗУ и работает CentOS. У меня есть доступ к корневой оболочке. PHP - версия 5.3.18. MySQL - это версия 5.1.66-cll.
Этот script находится за именем пользователя/паролем, и я не могу предоставить ему публичный доступ.
Отредактировано для добавления:
1) Спасибо всем за вашу помощь на сегодняшний день. Вы найдете более подробную информацию в моих ответах на конкретные комментарии пользователей в различных ответах ниже.
2) Сухозин определенно не установлен. Я проверил в нескольких местах, включая запуск script и проверку на константы и запуск php -v
3) В журнале apache нет записи конкретного сообщения об ошибке, которое я получаю. Ведение журнала включено в php.ini. Я пробивал через grep, чтобы искать весь журнал.
4) Возможно ли, что в этом случае сообщается о неправильной ошибке?
Ответы
Ответ 1
Наконец-то я нашел ответ. Подсказка исходила из ответа на pcguru: "Поскольку у сервера только 1 ГБ ОЗУ...".
По подозрению я посмотрел, имеет ли Apache собственные ограничения памяти, поскольку они могут повлиять на способность PHP выделять память. Прямо в верхней части httpd.conf я нашел это утверждение: RLimitMEM 204535125
Это помещается туда whm/cpanel. Согласно следующей веб-странице, whm/cpanel неправильно вычисляет ее значение на виртуальном сервере...
http://forums.jaguarpc.com/vps-dedicated/17341-apache-memory-limit-rlimitmem.html
script, который исчерпал всю память, проходит большую часть пути, поэтому я увеличил RLimitMEM до 268435456 (256 МБ) и повторно запустил script. Он завершил объединение массива и создал файл csv для загрузки.
ETA: после дальнейшего чтения о RLimitMEM и RLimitCPU я решил удалить их из httpd.conf. Это позволяет работать ini_set ('memory_limit', '### M'), и теперь я даю этому конкретному script дополнительную память, в которой он нуждается. Я также удвоил RAM на этом сервере.
Спасибо всем за вашу помощь в обнаружении этой довольно сложной проблемы, и особенно для pcguru, который придумал важную подсказку, которая заставила меня решить проблему.
Ответ 2
Поскольку сервер имеет только 1 ГБ оперативной памяти, я склоняюсь к тому, что вы на самом деле исчерпали системную память.
См. эту тему. Вы получаете ту же "PHP Fatal error: Out of memory", а не более общую "Неустранимая ошибка: допустимый размер памяти...". Ваша ошибка указывает на то, что система не может выделять больше памяти вообще, что означает, что даже внутренние функции PHP: s не могут выделять больше памяти, не говоря уже о вашем собственном коде.
Как PHP настроен для работы с Apache? Как модуль или как CGI?
Сколько процессов PHP вы можете запустить одновременно?
Есть ли свободное пространство подкачки?
Если вы используете PHP в качестве модуля в Apache, Apache имеет неприятную привычку хранить память, которую выделяет PHP-процесс. Угадайте, так как он не может перезапустить PHP-модуль у рабочего, просто перезагрузите его полностью. Каждый рабочий, который обслуживал PHP, с течением времени растет до предела памяти PHP, поскольку этот рабочий обслуживает script, который выделяет много оперативной памяти. Поэтому, если у вас много рабочих одновременно, каждый из которых использует 100 МБ +, вы быстро исчерпаете ОЗУ. Попробуйте ограничить число одновременных работников в Apache.
Ответ 3
Это не ответ на вопрос, почему ваш script умирает после определенного использования памяти, но вы можете обойти его, исключив ограничение памяти полностью внутри самого PHP скрипт:
ini_set('memory_limit', '-1');
Это опасно. Если у вас есть runaway script, PHP будет использовать память до тех пор, пока у вашего сервера не останется ни одного места для распределения и падения. Поэтому вы должны использовать это, только если вы уверены, что сам script не является проблемой, и только для проверки вывода.
Что касается того, что в PHP есть ограничение на использование памяти, no. Я лично запускаю скрипты с использованием памяти около 1 ГБ.
Ответ 4
Это может быть не ответ на вашу проблему, но если вы запустите PHP из командной строки, вы можете переопределить ограничение памяти из php.ini.
php -d memory_limit=321M my_script.php
Я не совсем уверен, что предел памяти по умолчанию через cli.
Кроме того, вы можете запустить php --ini
и проверить результаты.
Ответ 5
У вас есть бесконечный цикл где-то в вашем коде.