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 内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章