DOMDocument PHP 内存泄漏

Posted

技术标签:

【中文标题】DOMDocument PHP 内存泄漏【英文标题】:DOMDocument PHP Memory Leak 【发布时间】:2012-01-12 20:52:16 【问题描述】:

在 MAC 上的 MAMP 下运行 php 5.3.6,内存使用量每调用一次(3 到 8 次)就会增加,直到脚本因内存耗尽而死。我该如何解决这个问题?

libxml_use_internal_errors(true);
while(true)
 $dom = new DOMDocument();
 $dom->loadhtml(file_get_contents('http://www.ebay.com/'));
 unset($dom);
 echo memory_get_peak_usage(true) . '<br>'; flush();

【问题讨论】:

【参考方案1】:

使用libxml_use_internal_errors(true); 会抑制错误输出,但会构建一个连续的错误日志,并附加到每个循环中。禁用内部日志并抑制 PHP 警告,或者清除每个循环迭代的内部日志,如下所示:

<?php
libxml_use_internal_errors(true);
while(true)
 $dom = new DOMDocument();
 $dom->loadHTML(file_get_contents('ebay.html'));
 unset($dom);
 libxml_use_internal_errors(false);
 libxml_use_internal_errors(true);
 echo memory_get_peak_usage(true) . "\r\n"; flush();

?>

【讨论】:

非常感谢。我为此搜索过很多次,但从未想过要查看使用 libxml_use_internal_errors(true) 的含义 我怀疑这也是答案:***.com/questions/8188729/… 随意在其他答案和/或链接中交叉发布并传播爱。 @FrancisAvila 谢谢,很好发现:) 如果可以的话+100!哥们,你是救命恩人。一直以来,我都认为这是 DOMDocument 的错误,并且一直在修改它,是时候重构了。 =) 是啊!我被阻止试图知道我的内存泄漏来自哪里,而你指出了正确的方向。非常感谢!【参考方案2】:

根据@Tak 的回答和@FrancisAvila 的评论,我发现这个sn-p 更适合我:

while (true)

    $dom = new DOMDocument();

    if (libxml_use_internal_errors(true) === true) // previous setting was true?
    
        libxml_clear_errors();
    

    $dom->loadHTML(file_get_contents('ebay.html'));


print_r(libxml_get_errors()); // errors from the last iteration are accessible

这有额外的好处 1) 如果您需要通过 libxml_get_errors() 访问它们,则不会丢弃 last 解析的错误,以及 2) 仅在必要时调用 libxml_clear_errors(),因为libxml_use_internal_errors() 返回上一个设置状态。

【讨论】:

【参考方案3】:

您可以尝试强制垃圾收集器使用gc_collect_cycles() 运行,否则您将不走运。 PHP 没有公开任何东西来控制其内部内存使用,更不用说插件库使用的内存了。

【讨论】:

不幸的是,在脚本开始时使用gc_enable(),在每个循环结束时使用gc_collect_cycles(),内存不断消耗,返回0。【参考方案4】:

在本地测试您的脚本会产生相同的结果。但是,将 file_get_contents() 更改为本地 HTML 文件会产生一致的内存使用情况。可能是 ebay.com 的输出在每次调用 X 时都会发生变化。

【讨论】:

将 eBay 主页保存到本地 html 文件,然后使用它会产生相同的内存膨胀。包含的代码是我的问题代码的简化 - 它实际上是从本地缓存加载内容。 啊哈,找到了解决方案 - 将在单独的答案中发布

以上是关于DOMDocument PHP 内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

避免PHP-FPM内存泄漏导致内存耗尽

PHP内存泄漏分析定位

PHP内存泄漏分析定位

PHP Imagick 内存泄漏

如何修复 PHP 中的内存泄漏

排查内存泄漏最简单和直观的方法