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

php codeigniter memory xml-rpc memory-limit

1264567 просмотра

27 ответа

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

Автор: ArcticZero Источник Размещён: 25.07.2019 01:13

Ответы (27)


673 плюса

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

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

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

Автор: Jeff Размещён: 06.09.2013 02:24

203 плюса

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

Автор: Chris Lane Размещён: 25.10.2011 08:42

124 плюса

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

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

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

Автор: Basav Размещён: 21.03.2013 07:29

91 плюса

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

Постоянно

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

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

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

временный

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

Автор: Umair Idrees Размещён: 09.03.2014 02:55

59 плюса

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

Автор: troelskn Размещён: 18.02.2009 02:42

51 плюса

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

Автор: JamesAD-0 Размещён: 28.06.2015 05:19

45 плюса

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

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

memory_limit=4G

К этому:

memory_limit=4096M

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

Автор: Danny Beckett Размещён: 13.03.2017 11:26

21 плюса

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

function exhaustYourBytes()
{
    return exhaustYourBytes();
}
Автор: Kristen Waite Размещён: 08.05.2015 08:09

18 плюса

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

; 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

Автор: Prem Kumar Maurya Размещён: 05.12.2013 06:19

17 плюса

Вы можете исправить это, выбрав memory_limitfastcgi / 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

в

; Maximum amount of memory a script may consume (128 MB)
; http://php.net/memory-limit
memory_limit = 512M
Автор: Derick Fynn Размещён: 22.04.2015 12:41

14 плюса

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

ini_set('memory_limit', '1024M');
Автор: Gaurang P Размещён: 22.01.2015 12:46

12 плюса

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

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

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

<?php

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

Автор: sigmapi13 Размещён: 06.12.2012 05:48

11 плюса

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

$limit = ini_get('memory_limit');
ini_set('memory_limit', -1);
// ... do heavy stuff
ini_set('memory_limit', $limit);
Автор: mykeels Размещён: 07.02.2018 12:21

11 плюса

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

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

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

Автор: LK7889 Размещён: 25.02.2013 05:52

11 плюса

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

memory_limit = -1

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

Автор: Hasib Kamal Размещён: 26.06.2018 05:20

7 плюса

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

memory_limit = 64M

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

Автор: Sabi Размещён: 15.10.2013 01:44

7 плюса

Краш страница?

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

(Это происходит, когда 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
Автор: YumYumYum Размещён: 29.12.2016 02:13

6 плюса

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

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

class Proxy {

    private $actualObject;

    public function doSomething() {

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

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

Автор: madz Размещён: 12.07.2015 08:40

3 плюса

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

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

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

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

Автор: M61Vulcan Размещён: 30.01.2017 11:56

2 плюса

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

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

Автор: ratm Размещён: 22.02.2016 09:48

2 плюса

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

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

Автор: Janckos Размещён: 24.06.2015 03:14

2 плюса

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

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

Автор: Kerim Размещён: 15.08.2015 07:13

1 плюс

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

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

Уменьшая допустимый размер выделения путем добавления

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

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

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

На этом этапе вставьте 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 ().

Автор: David Spector Размещён: 16.07.2019 03:37

0 плюса

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

/**
* 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';
}
Автор: Dmitriy Kravchuk Размещён: 18.03.2019 02:55

0 плюса

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

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

Автор: LukeDS Размещён: 06.06.2019 11:01

-1 плюса

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

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

Автор: Pankaj Pratik Rai Размещён: 10.05.2019 11:09

-6 плюса

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

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

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

Автор: Omar Al-Azzawi Размещён: 11.02.2015 08:13
Вопросы из категории :
32x32