在每篇有关SimpleXML性能和内存使用的文章中,都提到所有解析的内容都存储在内存中,处理大型文件将导致大量内存使用.
但是最近我发现,使用SimpleXML处理大型文件不会导致大量内存使用,甚至会导致几乎没有内存使用.
有我的测试脚本:

<?php
error_reporting(E_ALL);
ini_set("display_errors", 1);
print "OS: " . php_uname() . "\n";
print "PHP version: " . phpversion() . "\n";

print round(memory_get_usage() / 1024 / 1024, 2) . " Mb\n";
$large_xml = '<?xml version="1.0" encoding="UTF-8"?><catalog><products>';
for ($i = 0; $i < 500000; $i++) {
    $large_xml .= "<product><id>{$i}</id><name>Product Name {$i}</name><description>Some Description {$i}</description><price>{$i}</price></product>\n";
}
$large_xml .= "</products></catalog>";
print round(memory_get_usage() / 1024 / 1024, 2) . " Mb\n";
$products_sxml = simplexml_load_string($large_xml);
print round(memory_get_usage() / 1024 / 1024, 2) . " Mb\n";
?>

我在Linux服务器上安装了此脚本,PHP版本:5.3.8,输出是:

操作系统:Linux 2.6.32-5-amd64#1 SMP Mon Feb 25 00:26:11 UTC 2013 x86\_64

PHP版本:5.3.8


0.6兆

65.98 Mb

65.98 Mb

所以我的问题是-其他人是否注意到它,这可能是对此的解释,因为我在网络上找不到任何地方的解释-甚至没有确认?

解决方法:

PHP的内存管理功能非常复杂,要准确地测量特定部分高级代码的影响非常困难.朱利安·保利(Julien Pauli)在a video of which is available here的PHP UK会议上就此进行了很好的(非常技术性的)演讲.

memory\_get\_usage可能对您撒谎有一些可能的原因:

首先,memory\_get\_usage带有一个可选参数$real\_usage,该参数区分已分配的内存量和正在使用的内存量-内存管理器一次分配一个内存块,因此它通常会要求OS分配比实际更多的内存.正在使用.当需要更多存储空间时,已经声明的内存将用完,这意味着不再需要分配内存.在这种情况下的测试表明,这与此处无关.
通常,在运行PHP的基础C代码中有不同的分配内存的方法.由于SimpleXML的大部分工作不是在Zend引擎中完成,而是在名为libxml2的第三方库中完成,因此内存分配将在此处完成,而不是在特定于PHP的分配例程中进行,例如在追加时使用到一个PHP字符串.

我从Julien Pauli的幻灯片中获取了以下功能,该功能查看了Linux内核对正在运行的PHP进程的看法,并找到了代表“ Resident Set Size”的行-实际分配的物理内存量,而非实际分配的内存量该过程已被要求保留:

function heap() {
    return shell_exec(sprintf('grep "VmRSS:" /proc/%s/status', getmypid()));
}

在您的示例代码中对此添加一个调用(以及对get\_memory\_usage(true)的调用),我得到以下输出,显示了在解析XML时“堆”内存的显着分配:

OS: Linux pink-marmalade 3.8.0-29-generic #42~precise1-Ubuntu SMP Wed Aug 14 16:19:23 UTC 2013 x86_64
PHP version: 5.3.10-1ubuntu3.8
memory_get_usage(): 0.61 Mb
memory_get_usage(true): 0.75 Mb
Heap: VmRSS:        6956 kB

memory_get_usage(): 65.99 Mb
memory_get_usage(true): 66.25 Mb
Heap: VmRSS:       74348 kB

memory_get_usage(): 65.99 Mb
memory_get_usage(true): 66.25 Mb
Heap: VmRSS:      761836 kB

标签: php, memory, simplexml

相关文章推荐

添加新评论,含*的栏目为必填