加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

PHP XML内存泄漏?

发布时间:2020-12-13 22:24:36 所属栏目:PHP教程 来源:网络整理
导读:我们的一个常规运行脚本中存在严重的内存泄漏,这些脚本会快速清除服务器上的可用内存.尽管经过了数小时的研究和实验,但我甚至无法对其进行研究. 这是代码: echo '1:'.memory_get_usage()."n";ini_set('memory_limit','1G'); echo '2:'.memory_get_usage().
我们的一个常规运行脚本中存在严重的内存泄漏,这些脚本会快速清除服务器上的可用内存.尽管经过了数小时的研究和实验,但我甚至无法对其进行研究.

这是代码:

echo '1:'.memory_get_usage()."n";
ini_set('memory_limit','1G');
    echo '2:'.memory_get_usage()."n";

$oXML = new DOMDocument();
    echo '3:'.memory_get_usage()."n";
$oXML->load('feed.xml'); # 556 MB file
    echo '4:'.memory_get_usage()."n";

$xpath = new DOMXPath($oXML);
    echo '5:'.memory_get_usage()."n";
$oNodes = $xpath->query('//feed/item'); # 270,401 items
    echo '6:'.memory_get_usage()."n";

unset($xpath);
    echo '7:'.memory_get_usage()."n";
unset($oNodes);
    echo '8:'.memory_get_usage()."n";
unset($oXML);
    echo '9:'.memory_get_usage()."n";

这是输出:

1:679016
2:679320
3:680128
4:680568
5:681304
6:150852408
7:150851840
8:34169968
9:34169448

如您所见,当我们使用xpath将节点加载到对象中时,内存使用量从681,304跳到150,852,408.我对此并不十分关注.

我的问题是,即使在销毁$oNodes对象之后,我们仍然停留在内存使用量34,169,968.

但真正的问题是PHP显示的内存使用量只是脚本占用的总内存的一小部分.直接从服务器上的命令行使用free -m,我们从3,295 MB内存到5,226 MB – 它永远不会再回落.每次运行此脚本时,我们都会丢失2 GB内存,而且我完全不知道为什么或如何修复它.

我尝试使用SimpleXML,但结果基本相同.我也研究了这三个线程,但没有找到任何有帮助的东西:

XML xpath search and array looping with php,memory issue

DOMDocument / Xpath leaking memory during long command line process – any way to deconstruct this class

DOMDocument PHP Memory Leak

我希望这很简单,我只是在俯视.

更新11/10:看起来内存最终被释放.我注意到在超过30分钟之后,突然又出现了一大块空地.但显然,最近这种情况还不够快,以防止服务器耗尽内存并锁定.

值得一提的是,我们在Red Hat 5.11上使用Apache 2.2.3运行PHP 5.3.15.我们正在努力更新所有这些版本的最新版本,因此在升级路径的某个地方,我们可能会发现这一点已经修复.不过,在此之前做这件事会很棒.

解决方法

最近遇到过和你一样的问题.我们需要从3gb xml文件中提取数据,并且还注意到服务器内存已达到其极限.有几种方法可以减少内存使用量;

>而不是使用导致大量内存使用的xpath(例如)file_get_contents.然后通过正则表达式进行搜索以查找所需数据
>将xml拆分成更小的部分.基本上它重新发明了xml文件,但你可以处理文件的最大大小(因此内存)

你提到30分钟后会释放一些内存.在30分钟内读取500mb xml是慢的方法.我们使用的解决方案是将3gb xml文件分成几个部分(aprox 200).我们的脚本在不到5分钟的时间内将所需数据(大约700k记录)写入我们的数据库.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读