Неустранимая ошибка: допустимый объем памяти 134217728 байт исчерпан (CodeIgniter + XML-RPC) - PullRequest
561 голосов
/ 18 февраля 2009

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

Клиентская POS основана на PHPPOS, и я реализовал модуль, который использует стандартную библиотеку XML-RPC для отправки данных о продажах в службу. Серверная система построена на CodeIgniter и использует библиотеки XML-RPC и XML-RPCS для компонента веб-сервиса. Всякий раз, когда я отправляю много данных о продажах (всего 50 строк из таблицы продаж и отдельные строки из sales_items, относящиеся к каждому товару в продаже), я получаю следующую ошибку:

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 54 bytes)

128M - это значение по умолчанию в php.ini, но я предполагаю, что это огромное число, которое нужно сломать. На самом деле, я даже пытался установить это значение равным 1024M, и все, что он делает, это занимает больше времени, чтобы выдать ошибку.

Что касается шагов, которые я предпринял, я попытался отключить всю обработку на стороне сервера и установил ее так, чтобы она возвращала стандартный ответ независимо от ввода. Тем не менее, я считаю, что проблема заключается в фактической отправке данных. Я даже пытался отключить максимальное время выполнения скрипта для PHP, но оно все равно выдает ошибку.

Ответы [ 26 ]

663 голосов
/ 06 сентября 2013

Изменение memory_limit на ini_set('memory_limit', '-1'); является , а не правильным решением. Пожалуйста, не делай этого.

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

Вероятно, вам следует попытаться отследить код в коде и исправить его.

202 голосов
/ 26 октября 2011

ini_set('memory_limit', '-1'); переопределяет значение по умолчанию Ограничение памяти PHP .

124 голосов
/ 21 марта 2013

Правильный способ - отредактировать файл php.ini. Отредактируйте memory_limit по вашему желанию.

Как видно из вашего вопроса, 128M (который является пределом по умолчанию) был превышен, поэтому в вашем коде что-то серьезно не так, поскольку это не должно занимать так много.

Если вы знаете, почему это занимает так много времени, и вы хотите, чтобы он установил memory_limit = 512M или выше, и вы должны быть хорошими.

89 голосов
/ 09 марта 2014

Распределение памяти для PHP можно регулировать постоянно или временно.

Постоянно

Вы можете навсегда изменить распределение памяти PHP двумя способами.

Если у вас есть доступ к файлу php.ini, вы можете отредактировать значение для memory_limit по своему желанию.

Если у вас нет доступа к файлу php.ini (и ваш веб-хост позволяет это), вы можете переопределить распределение памяти через файл .htaccess. Добавьте php_value memory_limit 128M (или любое другое желаемое распределение).

Временный

Вы можете настроить распределение памяти на лету из файла PHP. У вас просто есть код ini_set('memory_limit', '128M'); (или как вы хотите). Вы можете удалить ограничение памяти (хотя ограничения машины или экземпляра все еще могут применяться), установив значение «-1».

59 голосов
/ 18 февраля 2009

Очень легко получить утечки памяти в скрипте PHP - особенно если вы используете абстракцию, такую ​​как ORM. Попробуйте использовать Xdebug для профилирования вашего скрипта и выяснить, куда ушла вся эта память.

51 голосов
/ 28 июня 2015

При добавлении 22,5 миллиона записей в массив с помощью array_push я продолжал получать фатальные ошибки «исчерпал память», около 20 миллионов записей, используя 4G в качестве предела памяти в php.ini. Чтобы исправить это, я добавил утверждение

$old = ini_set('memory_limit', '8192M'); 

вверху файла. Сейчас все работает нормально. Я не знаю, есть ли у php утечка памяти, это не моя работа, и мне все равно. Мне просто нужно выполнить свою работу, и это сработало.

Программа очень проста:

$fh = fopen($myfile);
while (!feof($fh)) {
      array_push($file, stripslashes(fgets($fh)));
}  
fclose($fh);

Неустранимая ошибка указывает на строку 3, пока я не увеличил предел памяти, что устранена ошибка.

45 голосов
/ 13 марта 2017

Я продолжал получать эту ошибку, даже когда memory_limit установлен в php.ini, и значение считывается правильно с phpinfo().

Изменив это из этого:

memory_limit=4G

К этому:

memory_limit=4096M

Это исправило проблему в PHP 7.

21 голосов
/ 08 мая 2015

Когда вы видите вышеупомянутую ошибку - особенно если (tried to allocate __ bytes) является низким значением, это может быть индикатором бесконечного цикла, как функция, которая вызывает себя без выхода:

function exhaustYourBytes()
{
    return exhaustYourBytes();
}
18 голосов
/ 05 декабря 2013

После включения этих двух строк.
Это начало работать

; Determines the size of the realpath cache to be used by PHP. This value should
; be increased on systems where PHP opens many files to reflect the quantity of
; the file operations performed.
; http://php.net/realpath-cache-size
realpath_cache_size = 16k

; Duration of time, in seconds for which to cache realpath information for a given
; file or directory. For systems with rarely changing files, consider increasing this
; value.
; http://php.net/realpath-cache-ttl
realpath_cache_ttl = 120

17 голосов
/ 22 апреля 2015

Вы можете исправить это, изменив memory_limit на fastcgi / fpm

$vim /etc/php5/fpm/php.ini

Измените память, как со 128 на 512, см. Ниже

; Maximum amount of memory a script may consume (128MB)
; http://php.net/memory-limit
memory_limit = 128M

до

; Maximum amount of memory a script may consume (128MB)
; http://php.net/memory-limit
memory_limit = 512M
...