it-swarm.com.ru

Неустранимая ошибка: допустимый объем памяти 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, и он все еще выдает ошибки.

562
ArcticZero

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

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

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

663
Jeff

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

202
Chris Lane

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

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

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

124
Basav

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

Постоянно

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

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

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

Временный

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

89
Umair Idrees

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

59
troelskn

Добавляя 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, пока я не увеличил предел памяти, что устранило ошибку.

51
JamesAD-0

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

Изменяя это от этого:

memory_limit=4G

К этому:

memory_limit=4096M

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

45
Danny Beckett

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

function exhaustYourBytes()
{
    return exhaustYourBytes();
}
21
Kristen Waite

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

; 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

18
Prem Kumar Maurya

Вы можете исправить это, изменив 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
17
Derick Fynn

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

ini_set('memory_limit', '1024M');
14
Gaurang P

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

memory_limit = -1

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

12
Hasib Kamal

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

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

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

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

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

11
LK7889

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

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

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

<?php

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

11
sigmapi13

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

memory_limit = 64M

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

7
Sabi

CRASH-страница? enter image description here

(Это происходит, когда MySQL должен запрашивать большие строки, по умолчанию для momory_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, чтобы исправить проблему CRASH Page.

# grep memory_limit /etc/php.ini
memory_limit = 512M
6
YumYumYum

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

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

class Proxy {

    private $actualObject;

    public function doSomething() {

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

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

6
madz

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

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 4096 bytes) in C:\\workspace\image_management.php on line 173

Поскольку поиск ошибки привел меня сюда, я подумал, что упомяну, что это не всегда технические решения, описанные выше, а что-то более простое. В моем случае это был Firefox. До того, как я запустил программу, она уже использовала 1,157M.
Оказывается, я немного смотрел 50-минутное видео за несколько дней, и это все испортило. Это исправление, которое эксперты исправляют, даже не задумываясь об этом, но для таких, как я, это стоит иметь в виду.

3
M61Vulcan

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

Updating memory_limit on WHM 11.48.4

2
Janckos

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

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

2
ratm

Я считаю это полезным, если включить или требовать:
dbconnection.php , _functions.php в файлах, которые фактически обрабатываются,
, а не в заголовке. Который включен сам.

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

2
Kerim

Использование yield также может быть решением https://www.php.net/manual/en/language.generators.syntax.php

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

0
LukeDS

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

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

Просто добавьте ini_set ('memory_limit', '-1'); линия в верхней части вашей веб-страницы. И вы можете установить свою память в соответствии с вашими потребностями в месте от -1 до 16M и т.д.

0
Pankaj Pratik Rai