Неустранимая ошибка: разрешенный размер памяти 134217728 байт исчерпан (CodeIgniter + XML-RPC)

У меня есть несколько систем точек продаж (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, но он все еще не работает.


person ArcticZero    schedule 18.02.2009    source источник
comment
Немного запуталась ... где ошибка - в клиенте или на сервере? И на каком этапе ... отправка клиента, получение сервера, обработка сервера, отправка сервера, получение клиента или обработка клиента?   -  person Greg    schedule 18.02.2009
comment
Как / где вы устанавливаете memory_limit на 1024M?   -  person James Socol    schedule 18.02.2009
comment
Кажется, что ошибка возникает либо во время отправки клиентом, либо при получении сервером. Я попытался отключить всю серверную обработку и настроить ее для отправки стандартного ответа независимо от отправленных данных. Ошибка возникает, если я отправляю определенный объем данных. Я меняю настройку PHP.ini.   -  person ArcticZero    schedule 18.02.2009
comment
Вот код, который я использую ... Я также включил библиотеку XML-RPC, используемую для клиента: yousendit.com/download/U0d4SlIzcVg4aVBIRGc9PQ (клиент)   -  person ArcticZero    schedule 19.02.2009
comment
ограничение памяти 128 МБ, удвойте: ini_set('memory_limit', '256M');   -  person    schedule 02.08.2013
comment
Сводка отвергла всех, кто просто игнорировал ответы на утечки, людей, которые путали CodeIgniter с Drupal, и людей, которые просто копировали и вставляли ответы других людей, чтобы получить очки. Качество ответов в этом ужасном.   -  person Matti Virkkunen    schedule 12.12.2013
comment
Ни один из ответов, похоже, не касается того факта, что размер выделенной памяти на самом деле не превышен (согласно ошибке), выглядит как ситуация с бесконечным циклом.   -  person Robert Sinclair    schedule 31.05.2021


Ответы (31)


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

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

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

person Jeff    schedule 06.09.2013
comment
@Jeff, ты, наверное, прав в 95% случаев. Однако бывают случаи, когда вам действительно нужно больше памяти. Например, предположим, что ваше приложение загружает большой объем данных в память для обработки (скажем, спецификация материалов с 15 тыс. Компонентов). Не всегда в коде есть ошибки, иногда вам просто нужно немного больше памяти (например, 256 МБ вместо 128 МБ). Однако я согласен с тем, что устанавливать его на -1 ужасно плохо. Но регулировка предела памяти для разумных ситуаций во время выполнения вполне приемлема imho. - person Pyrite; 10.05.2014
comment
@pyrite да, вы правы, что иногда процессу требуется больше памяти, но вы должны увеличить лимит памяти до некоторого логического количества, например 256 МБ, как вы сказали, или 512 МБ, почему бы и нет, НО не -1;) - person Lukas Lukac; 18.08.2014
comment
@jeff Я полностью согласен, значение -1 может быть полезно только в средах разработки для целей тестирования. - person Esolitos; 03.03.2015
comment
@Pyrite в тех случаях, которые вы указали для оставшихся 5%, читают данные по частям и используют воркер для их обработки вместо использования дополнительной памяти. Это решение также будет масштабироваться, в то время как ваше предложение не сработает, за исключением того, что вы продолжаете заполнять все больше и больше памяти на своем сервере с течением времени, если объем данных будет расти. - person floriank; 12.07.2015
comment
Чаще всего эта проблема в ORM, когда вы пытаетесь получить все данные, которые намного превышают предел памяти php. Например, когда вы пытаетесь создать ежемесячный отчет. - person Stepchik; 08.01.2017
comment
Есть лучшее решение - не хранить все данные в памяти и использовать курсоры базы данных и выход php, извлекать данные по строкам и помещать их в свой отчет. Вот небольшой пример с курсорами и генераторами доходности github.com/stepchik/stuff/tree/master / php_memory_problem - person Stepchik; 08.01.2017
comment
что отслеживать при новой установке, в журнале ошибок просто указано, что Фатальная ошибка: допустимый размер памяти 134217728 байт исчерпан (попытался выделить 4096 байт) - person Yogesh Trivedi; 10.04.2017
comment
как отследить это в localhost? - person ehsan asarzadeh; 31.10.2020
comment
Отличный ответ. Мне нравится, что. Режущая головка - не решение. это может быть опасно - person Ariful Islam; 28.04.2021

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

person Chris Lane    schedule 25.10.2011
comment
где это менять ?! Я нахожу эту строку только в php.ini - person Alisso; 22.03.2013
comment
Это действительно помогает в определенных ситуациях, когда вам абсолютно необходимо что-то завершить, а затем вернуть это значение к разумному. - person DrCord; 04.10.2013
comment
@williamcarswell; -1 - это значение, которое PHP в этом контексте понимает как неограниченно. - person Alix Axel; 09.11.2013
comment
в сочетании с max_execution_time = -1 это может потреблять все ресурсы, которые сервер может сэкономить. - person baldrs; 23.12.2013
comment
@ ArseniuszŁozicki - он также потребляет ресурсы, которые сервер не может сэкономить. - person Ken Williams; 02.02.2014
comment
Жалко, что за это так много положительных голосов. Установка точного значения с помощью редактирования php.ini или ini_set - это совершенно правильное решение, когда людям нужно больше памяти. Установка неограниченного количества - опасный взлом :( - person Jeff Davis; 07.03.2014
comment
@JeffDavis Это лучший ответ. Я устанавливаю это часто, потому что у меня есть PHP-скрипты, которые я запускаю на своем рабочем столе, и мне наплевать на опасные последствия. Я просто хочу, чтобы скрипт не выдал эту ошибку, вот и все. - person user1767586; 24.05.2014
comment
@ user1767586 затем установите для него разумное значение. Вы можете предотвратить выдачу ошибки скриптом, установив для него значение 1024M. Если в этом ответе указано ini_set ('memory_limit', '1024M'); Вы можете скопировать это и все будет в порядке. Устанавливая его на -1, вы настраиваете себя на сценарий, который потребляет всю память. Особенно, если вы делаете это регулярно. Заключение опасностей в кавычки не делает их менее опасными. Вы действительно могли бы залить свой хост-сервер. Может начать уничтожать данные. Не знаю, может, работу потеряешь? Для меня это звучит довольно опасно. : | - person Jeff Davis; 26.05.2014
comment
memory_get_usage(true) может пригодиться, если вы пытаетесь выяснить точно где происходит сбой памяти. Таким образом вы можете попытаться улучшить производительность вашего скрипта без чрезмерного потребления памяти. - person mathielo; 10.11.2014
comment
это неправильный способ, даже если за него много голосов. это приведет к снижению производительности кода. - person albanx; 21.04.2015
comment
При всем уважении, этот ответ должен быть предан забвению. Это решение устраняет одну проблему, но вводит множество других проблем. Это все равно, что продать одного дьявола, которого у вас есть, в обмен на еще несколько десятков дьяволов. Как уже было предложено, (1) увеличить доступность глобальной памяти PHP в memory_limit в php.ini и / или (2) диагностировать утечку памяти. - person jfmercer; 06.05.2015
comment
Печально видеть, что ответ на +161 голос и -3 голоса одинаковый :( - person akarthik10; 21.08.2015
comment
Это очень плохая идея - person user3806549; 17.12.2015
comment
Всегда думайте, прежде чем использовать это, если это действительно необходимо. - person kiltek; 15.02.2017
comment
Очень хорошо работает с высоконагруженной производственной программой, огромное спасибо! - person Mantisse; 14.12.2017
comment
В случае, если кто-то с проектом laravel задается вопросом, куда его поставить! Если код выполняется при вызове веб-страницы, вам нужно поместить его в index.php в самую первую строку после запуска ‹? Php. Если код запускается из любой команды ремесленника, такой как очередь, вам нужно добавить это в файл ремесленника в том же месте, что и говорилось ранее ... - person Ashiq; 15.10.2019
comment
Я получал эту ошибку локально в vscode, вызванную моими расширениями php, поэтому она отлично работала. - person Lamellama; 11.05.2020

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

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

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

person Basav    schedule 21.03.2013
comment
Честно говоря, если вы кешируете серьезные объемы данных, это правильный ответ. 128M недостаточно для некоторых скриптов. 512 Мбайт или 1024 Мбайт часто бывает достаточно, но вам придется решать индивидуальный вопрос. - person Jeff Davis; 07.03.2014
comment
Да, но постарайтесь избегать огромного использования памяти, если количество пользователей будет больше. - person Basav; 09.07.2014
comment
memory_limit = -1; установить в php.ini - person ; 04.08.2014
comment
@YumYumYum Это удаляет memory_limit, который вам нужен, только если вы контролируете использование памяти каким-либо другим способом. ОС убьет процесс, если в какой-то момент он потребует большой объем памяти. - person Flimm; 10.09.2015
comment
Итак, если вы запускаете скрипт, который использует много памяти, но вам нужно запустить его только один раз, можете ли вы просто увеличить лимит памяти для процесса во время выполнения, а затем снова снизить лимит памяти после разового скрипт запускается? - person chromechris; 16.02.2020

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

Постоянно

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

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

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

Временный

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

person Umair Idrees    schedule 09.03.2014
comment
Спасибо, я не подумал проверить, установил ли кто-нибудь значение в .htaccess, которое переопределяет php.ini, и я не мог понять, почему +1 - person HostMyBus; 16.06.2016
comment
Для тех, кому требуется временная установка с помощью команд: php -d memory_limit=256M your_php_file.php или php -d memory_limit=256M artisan ... - person The Anh Nguyen; 11.12.2020

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

person troelskn    schedule 18.02.2009
comment
Пойду попробую Xdebug. Я никогда не использовал его раньше, поэтому мне придется его прочитать. Спасибо за ответ! Надеюсь, я скоро найду ответ на этот вопрос ... - person ArcticZero; 18.02.2009
comment
Помните, что PHP использует подсчет ссылок для управления памятью. Поэтому, если у вас есть циклические ссылки или глобальные переменные, эти объекты не будут переработаны. Обычно это корень утечек памяти в PHP. - person troelskn; 18.02.2009
comment
Xdebug показывает, что за мою утечку памяти отвечает библиотека CI Xmlrpc.php. Случайно, возникнут ли какие-либо проблемы с библиотеками XML-RPC CodeIgniter, о которых мне следует знать? Я попытался отключить всю обработку на стороне сервера, но у него все равно заканчивается память, если я скармливаю ему достаточно данных. - person ArcticZero; 18.02.2009
comment
Я не знаю / использую CI, поэтому не знаю. Но вам, вероятно, следует попытаться найти объект, который не освобождается после использования - скорее всего, из-за циклической ссылки. Это детективная работа. - person troelskn; 19.02.2009
comment
Я все время использую ORM (доктрину), и у меня не было ни одной утечки памяти. - person Alberto Gaona; 26.06.2014
comment
Это единственный ответ, который советует решить проблему. Другие ответы заставляют память перевязать симптом и игнорировать болезнь. - person Chris Baker; 25.04.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, пока я не увеличил предел памяти, что устранило ошибку.

person JamesAD-0    schedule 28.06.2015
comment
ты имеешь ввиду ini_set('memory_limit', '8192M');? - person Gogol; 06.01.2016
comment
Какая роскошь было бы иметь время пойти и оптимизировать сценарий для чего-то в этом роде. Или исследуйте, сравнивайте и изучайте инструменты ETL или что-то в этом роде. В реальном мире мы увеличиваем объем памяти, делаем то же самое и идем дальше. - person Matthew Poer; 10.05.2018

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

Изменив это:

memory_limit=4G

К этому:

memory_limit=4096M

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

person Danny Beckett    schedule 13.03.2017

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

function exhaustYourBytes()
{
    return exhaustYourBytes();
}
person Kristen Waite    schedule 08.05.2015

Корневой каталог вашего сайта:

ini_set('memory_limit', '1024M');
person Gaurang P    schedule 22.01.2015
comment
это сработало для меня. люблю однострочные решения. +1 для простоты - person Steve C; 04.08.2016

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

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

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

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

to

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

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

; 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

person Prem Kumar Maurya    schedule 05.12.2013

В Drupal 7 вы можете изменить ограничение памяти в файле settings.php, расположенном в папке sites / default. В строке 260 вы увидите следующее:

ini_set('memory_limit', '128M');

Даже если ваши настройки php.ini достаточно высоки, вы не сможете использовать более 128 МБ, если это не установлено в вашем файле settings.php Drupal.

person LK7889    schedule 25.02.2013
comment
Нет в Drupal7 такой строчки кода в settings.php - person FLY; 19.06.2013
comment
Также нет строки в settings.php для drupal 6 - person AllisonC; 01.03.2018

Измените ограничение памяти в файле php.ini и перезапустите Apache. После перезапуска запустите функцию phpinfo (); из любого файла PHP для memory_limit подтверждения изменения.

memory_limit = -1

Ограничение памяти -1 означает, что ограничение памяти не установлено. Сейчас это максимум.

person Hasib Kamal    schedule 26.06.2018

Для пользователей Drupal это ответ Криса Лейна:

ini_set('memory_limit', '-1');

работает но надо ставить сразу после открытия

<?php

в файле index.php в корневом каталоге вашего сайта.

person sigmapi13    schedule 06.12.2012

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

$limit = ini_get('memory_limit');
ini_set('memory_limit', -1);
// ... do heavy stuff
ini_set('memory_limit', $limit);
person mykeels    schedule 07.02.2018

Просто добавьте строку ini_set('memory_limit', '-1'); вверху своей веб-страницы.

И вы можете установить свою память в соответствии с вашими потребностями вместо -1, на 16M и т. Д.

person Pankaj Pratik Rai    schedule 10.05.2019
comment
Похоже, это говорит то же самое, что и многие существующие ответы. Лучше всего добавлять ответ на популярный вопрос, только если новый материал предлагает что-то новое. - person halfer; 10.05.2019

PHP 5.3+ позволяет изменять ограничение памяти, помещая файл .user.ini в папку public_html. Просто создайте указанный выше файл и введите в нем следующую строку:

memory_limit = 64M

Некоторые хосты cPanel принимают только этот метод.

person Sabi    schedule 15.10.2013

Страница сбоя?

Введите здесь описание изображения

(Это происходит, когда MySQL запрашивает большие строки. По умолчанию для memory_limit установлено значение small, что было безопаснее для оборудования.)

Вы можете проверить состояние существующей памяти вашей системы, прежде чем увеличивать php.ini:

# free -m
             total       used       free     shared    buffers     cached
Mem:         64457      63791        666          0       1118      18273
-/+ buffers/cache:      44398      20058
Swap:         1021          0       1021

Здесь я увеличил его, как показано ниже, а затем сделал service httpd restart, чтобы исправить проблему со страницей сбоя.

# grep memory_limit /etc/php.ini
memory_limit = 512M
person Community    schedule 29.12.2016
comment
На какое число (строку и столбец?) Следует смотреть после выполнения команды free -m, чтобы определить новый предел memory_limit? - person kiradotee; 23.01.2020

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

Например, прокси-класс, который имеет то же имя, что и функция объекта, который будет его прокси.

class Proxy {

    private $actualObject;

    public function doSomething() {

        return $this->actualObjec->doSomething();
    }
}

Иногда вы можете забыть принести этот маленький фактический член Objec, и поскольку прокси-сервер действительно имеет этот метод doSomething, PHP не выдаст вам никаких ошибок, а для большого класса он может быть скрыт от глаз на пару минут, чтобы выяснить, почему происходит утечка памяти.

person madz    schedule 12.07.2015
comment
И еще один совет: вы можете поместить die('here') в свой код и переместить этот оператор, чтобы увидеть, где начинается рекурсия. - person toddmo; 06.05.2018

У меня была ошибка ниже при работе с набором данных меньшего размера, чем работало ранее.

Неустранимая ошибка: разрешенный размер памяти 134217728 байт исчерпан (попытка выделить 4096 байт) в C: \ workspace \ image_management.php в строке 173

Поскольку поиск неисправности привел меня сюда, я подумал, что упомянул, что это не всегда технические решения из предыдущих ответов, а что-то более простое. В моем случае это был Firefox. До того, как я запустил программу, она уже занимала 1157 МБ.

Оказалось, что я смотрел 50-минутное видео понемногу в течение нескольких дней, и это все испортило. Это своего рода исправление, которое эксперты исправляют, даже не задумываясь о нем, но для таких, как я, стоит помнить о нем.

person M61Vulcan    schedule 30.01.2017
comment
У меня сегодня был похожий случай в Google Chrome. Я крайне скептически отнесся к этому ответу ... однако он показал, что мое исчерпание байтов исчезло после того, как я открыл окно в режиме инкогнито и снова запустил тот же сценарий! Исследования продолжаются. - person mickmackusa; 23.04.2020

Использование yield также может быть решением. См. синтаксис генератора.

Вместо того, чтобы изменять PHP.ini файл для большего объема памяти, иногда реализация yield внутри цикла может решить проблему. Yield делает вместо того, чтобы выгружать все данные сразу, он читает их один за другим, экономя много памяти.

person LukeDS    schedule 06.06.2019
comment
PHP.ini? Разве это не php.ini? - person Peter Mortensen; 25.07.2019

Запуск такого сценария (например, cron): php5 /pathToScript/info.php вызывает ту же ошибку.

Правильный способ: php5 -cli /pathToScript/info.php

person ratm    schedule 22.02.2016

Если вы используете VPS (виртуальный частный сервер) на базе WHM, вы можете обнаружить, что у вас нет прав на редактирование PHP.INI напрямую; система должна это делать. На панели управления хоста WHM перейдите в Конфигурация службы Редактор конфигурации PHP и измените memory_limit:

Обновление memory_limit в WHM 11.48.4

person Fred Noriega    schedule 24.06.2015

Я считаю, что это полезно при включении или требовании _dbconnection.php_ и _functions.php в файлах, которые фактически обрабатываются, а не в заголовке. Что входит в себя.

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

person Kerim    schedule 15.08.2015

В моем случае на Mac (Catalina - Xampp) не было загруженного файла, поэтому мне пришлось сделать это в первую очередь.

sudo cp /etc/php.ini.default /etc/php.ini
sudo nano /etc/php.ini

Затем измените memory_limit = 512M

Затем перезапустите Apache и проверьте, загружен ли файл.

php -i | grep php.ini

Результат был

Configuration File (php.ini) Path => /etc
Loaded Configuration File => /etc/php.ini

Наконец проверьте

php -r "echo ini_get('memory_limit').PHP_EOL;"
person DragonFire    schedule 21.01.2021

Наиболее частой причиной этого сообщения об ошибке для меня является пропуск оператора ++ в инструкции PHP for. Это приводит к тому, что цикл будет продолжаться вечно, независимо от того, сколько памяти вы позволите использовать. Это простая синтаксическая ошибка, но ее трудно обнаружить компилятору или исполняющей системе. Нам легко исправить, если мы думаем его искать!

Но предположим, что вам нужна общая процедура для ранней остановки такого цикла и сообщения об ошибке? Вы можете просто инструментировать каждую из ваших петель (или, по крайней мере, самые внутренние петли), как описано ниже.

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

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

Тогда у вас может остаться программа, которая завершается, но по-прежнему трудно отлаживать.

Независимо от того, завершается ваша программа или нет, настройте свой код, вставив BreakLoop() вызовов внутрь вашей программы, чтобы получить контроль и выяснить, какой цикл или рекурсия в вашей программе вызывает проблему.

Определение BreakLoop следующее:

function BreakLoop($MaxRepetitions=500,$LoopSite="unspecified")
    {
    static $Sites=[];
    if (!@$Sites[$LoopSite] || !$MaxRepetitions)
        $Sites[$LoopSite]=['n'=>0, 'if'=>0];
    if (!$MaxRepetitions)
        return;
    if (++$Sites[$LoopSite]['n'] >= $MaxRepetitions)
        {
        $S=debug_backtrace(); // array_reverse
        $info=$S[0];
        $File=$info['file'];
        $Line=$info['line'];
        exit("*** Loop for site $LoopSite was interrupted after $MaxRepetitions repetitions. In file $File at line $Line.");
        }
    } // BreakLoop

Аргумент $ LoopSite может быть именем функции в вашем коде. На самом деле в этом нет необходимости, поскольку сообщение об ошибке, которое вы получите, укажет вам на строку, содержащую вызов BreakLoop ().

person David Spector    schedule 16.07.2019

измените ;memory_limit=512M на ;memory_limit=-1 в  введите описание изображения здесь

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

person Hossein Azad    schedule 13.09.2020

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

/**
* Memory leak function that illustrates unintentional bad code
* @param $variable - input function that will be assigned a new value
* @return null
**/
function doSomehting($variable){
    $variable = 'set value';
    // Or
    $variable .= 'set value';
}
person Dmitriy Kravchuk    schedule 18.03.2019

Я потратил два дня на поиск решения этой проблемы и понял, что это было причиной вызова с PDO, когда я позвонил

$stmt->bindParam(":PERIOD", $period); 

а период переменных был

empty string ''

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

Обновление: я также столкнулся с этой ошибкой с помощью метода $ pdo- ›query (). Я использовал $ pdo-› prepare () и работал хорошо, поэтому, пока у меня был

$sql = "SELECT * FROM COURSE_DETAILS where ACTIVE = 1 AND COURSE_DETAILS_ID = $id";
$stmt = getConnection()->query($sql);
$courseDetails = $stmt->fetchAll(PDO::FETCH_ASSOC)

тогда я изменил это на

$sql = "SELECT * FROM COURSE_DETAILS where ACTIVE = 1 AND COURSE_DETAILS_ID = ?";
$stmt = getConnection()->prepare($sql);
$stmt->execute(array($id)); 

и волшебным образом исчезла ошибка памяти!

person Juan Pablo G    schedule 11.11.2020

Этот вопрос был задан несколько лет назад, поэтому, хотя мои факты не совпадают, я также недавно получил эту ошибку при разборе таблицы html на сервере в цикле. Причина ошибки заключалась в том, что HTML-код был проанализирован с использованием двойных кавычек, которые были объединены с переменной $table, при одновременном объединении строк в многострочном формате.

$table = "<table>\n";
    $table .= "<tbody>\n";
        foreach ($data as $item) {
            $table .= "<tr>\n";
                // this caused the Fatal Error: Allowed Memory Size of 134217728 Bytes Exhausted
                $table .= "<td>$item->description</td><td>$item->qty</td>" .  
                $table .= "<td>$item->price_incl</td><td>$item->price->vat</td>" .
                $table .= "<td>$item->price_excl</td><td>$item->available</td>" .
            $table .= "</tr>\n";
        }
    $table .= "</tbody>";
$table .= "</table>\n";

Вышеупомянутая ошибка показалась мне странной, но, учитывая, что я уже конкатенировал строку с переменной $table, теперь кажется глупым, что я пробовал это. Решением было либо удалить конкатенацию переменных в строке 7 и 8, либо удалить символ конкатенации конечной строки из строк 6, 7 и 8.

person Hmerman6006    schedule 01.05.2021

Когда я удалил из кода следующие строки, все заработало!

set_include_path(get_include_path() . get_include_path() . '/phpseclib');
include_once('Net/SSH2.php');
include_once('Net/SFTP.php');

Эти строки были включены в каждый файл, который я запускал. При запуске файлов один за другим все работало нормально, но когда все файлы запускались вместе, у меня возникла проблема с утечкой памяти. Почему-то "include_once" не включает что-то один раз, или я что-то делаю не так ...

person Omar Al-Azzawi    schedule 11.02.2015
comment
set_include_path(get_include_path() . get_include_path().'/phpseclib'); Это добавит путь '/ phpseclib' один раз для каждого файла, в котором есть строка ... так что он может добавлять его много раз! Я бы посоветовал поместить его в файл настроек и include_once файл настроек. - person Farfromunique; 21.06.2017