我们的一项常规脚本存在严重的内存泄漏问题,会很快耗尽服务器上的可用内存。虽然我已经花费了很多时间进行研究和实验,但是我仍然无法解决这个问题。
以下是代码:
正如您所看到的,当我们使用xpath将节点加载到对象中时,内存使用量从681,304跳升到了150,852,408。我并不太担心这个。
我的问题是,即使在销毁$oNodes对象之后,我们仍然停留在34,169,968的内存使用量上。
但是,真正的问题是PHP显示的内存使用量只是脚本所消耗总内存的一小部分。直接从服务器命令行使用“free -m”,我们从3,295 MB的内存使用量增加到5,226 MB,而且它永远不会回落。每次运行此脚本,我们就会损失2 GB的内存,我完全不知道为什么或如何解决它。
我尝试使用SimpleXML,但结果基本相同。我还研究了这三个线程,但没有找到任何有用的东西:
以下是代码:
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,但结果基本相同。我还研究了这三个线程,但没有找到任何有用的东西:
DOMDocument / Xpath在长时间命令行进程中泄漏内存 - 有没有方法来解构这个类?
我希望这是我忽略的一些容易解决的问题。
更新11/10:看起来内存最终会被释放。我注意到在30分钟左右,突然又释放了一个大块。然而,最近这还不够快,无法防止服务器耗尽内存并锁定。
值得一提的是,我们正在Red Hat 5.11上以Apache 2.2.3和PHP 5.3.15运行。我们正在努力更新所有这些的最新版本,因此在升级路径的某个地方,我们可能会发现这个问题已经被修复了。不过最好在那之前解决它。
unset
之前,请尝试查看$oNodes
有多少个引用。参见:http://php.net/manual/zh/features.gc.refcounting-basics.php - Machavity