SimpleXml использует огромное количество оперативной памяти при записи файла - PullRequest
0 голосов
/ 29 мая 2018

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

Я использую Laravel 5.6с PostGreSQL 10 и SimpleXml.

Ниже приведен фрагмент кода, работающего над созданием XML-документа.

 $startTime = time();

    $feedXml = new SimpleXMLElementExtended('<?xml version="1.0" encoding="UTF-8"?><products></products>',
        LIBXML_NOERROR | LIBXML_NOWARNING);

$storeChannelProducts =
        StoreChannelProduct::where('store_channel_id', $storeChannelId)
                           ->whereNull('channel_data_exclude_reason')
                           ->get();

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

    /*
     * Increase memory and execution time
     */
    ini_set('memory_limit', (384 + min_max((count($storeChannelProducts)) * 2.5, 0, 1728)).'M');
    set_time_limit(min_max((count($storeChannelProducts)) * 0.5, 30, 3600));

    $storeChannelProducts->keyBy('store_channel_product_id');
    $i = 1;
    foreach ($storeChannelProducts as $storeChannelObject) {

        \Log::debug('Feed building after making record ' . $i);
        \Log::debug('Memory usage: '. memory_get_usage());
        \Log::debug('Time since start = '.(time() - $startTime));

        $i++;

        if (gc_enabled()) {
            gc_disable();
        }

        $storeChannelProducts->forget($storeChannelObject->store_channel_product_id);
        unset($storeChannelObject, $feedProduct, $product);
    }

    \Log::debug('End of feed building');

В цикле foreach я получаю данные из своих моделей и использую addChildи методы addAttribute для добавления данных в мой XML-файл.Коллекция, которую я зацикливаю, состоит из около 4600 произведений.

Когда я запускал команду, терминал выдавал «Убит!»как вывод, и когда я снова запустил его с использованием памяти на другой вкладке, я заметил, что примерно через 1 минуту объем используемой оперативной памяти составил 1000 МБ, примерно через 3 минуты объем ОЗУ стабилизировался на уровне около 2370 МБ, а с 5,5 минут объем памяти снова начал увеличиваться.пока он не вышел из строя чуть более 8 минут, когда он использовал 5000 МБ ОЗУ для этой одной команды.

Я уже пробовал несколько вещей, таких как сброс всех переменных, которые сбрасываются на следующей итерации цикла foreachи использование gc_disable, поскольку я где-то читал, что сборщик мусора может использовать много оперативной памяти для проверки всех узлов XML, чтобы увидеть, какие из них все еще активны.

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

...