Ошибка PHP из памяти, хотя memory_limit не достигнут - программирование
Подтвердить что ты не робот

Ошибка 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) Возможно ли, что в этом случае сообщается о неправильной ошибке?

4b9b3361

Ответ 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

У вас есть бесконечный цикл где-то в вашем коде.