SimpleXml在写入文件时使用大量RAM

时间:2018-05-29 09:45:00

标签: php laravel out-of-memory simplexml

我的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分钟后使用的RAM为1000MB,大约3分钟后RAM稳定在2370MB左右,从5.5分钟开始RAM再次增加直到它在8分钟的时间内崩溃了,因为这个命令使用了5000MB的RAM。

我已经尝试了一些事情,例如取消设置在foreach循环的下一次迭代中重置的所有变量并使用gc_disable,因为我在某处读到垃圾收集器可以使用大量RAM来检查所有XML节点以查看哪些他们仍然活跃。

我希望有人能够就如何解决此问题或减少正在使用的RAM提供任何见解或建议。

0 个答案:

没有答案