为什么全局$ _SERVER数组占用内存的13倍?

时间:2010-12-08 02:59:02

标签: php memory-management global-variables

使用普通PHP数组创建新数组(和元素)时,以下代码在带有和不带APC的PHP 5.3中使用360字节。即使向$ _GET添加元素也只使用304个字节。但是,在$ _SERVER中创建一个额外的元素时,相同的代码使用4,896字节!

$mem = memory_get_usage();

//$array = array('HTTP_X_REQUESTED_WITH' => NULL);
$_SERVER['HTTP_X_REQUESTED_WITH'] = NULL;
//$_GET['HTTP_X_REQUESTED_WITH'] = NULL;

print (memory_get_usage() - $mem).' bytes<br>';
print memory_get_usage().' bytes (process)<br>';
print memory_get_peak_usage(TRUE). ' bytes (process peak)<br>';
print (memory_get_usage() - $mem).' bytes<br>';

世界上有什么原因导致$ _SERVER数组使用如此多的额外内存?

2 个答案:

答案 0 :(得分:4)

如果我正在开发PHP,我不会担心像这样的低级细节。可能发生的是你已达到$ _SERVER的容量限制,并且PHP必须创建一个新哈希表,其大小是当前哈希表的两倍。由于这些是有序关联数组,因此哈希表的每个元素都有相当大的开销成本,甚至是未填充的点。

如果您对此过程的机制感兴趣,请参阅zend_hash.c第418行。

要对此进行测试,请获取$ _SERVER的var_dump,然后将其放入脚本中。请确保不仅仅测试虚拟哈希表有以下几个原因:(1)实际上有不同的C代码路径用于php“动态数组”与php“哈希表”(它为你转换它们),以及(2)问题可能是将这么多字符串复制到新的哈希表以避免线程安全或指针开销。

答案 1 :(得分:2)

Mike解释PHP如何动态地为数组分配内部哈希表。对于动态分配数组,大小加倍是非常有效的。

然而,当脚本启动时,$ _SERVER,$ _REQUEST,$ _POST,$ _GET和$ _ENV superglobals都是固定大小。它们通常也不会被编辑(我不鼓励它)。

很可能它们是使用足够大的哈希表创建的,以适应当前的大小。然后,任何添加都会触发动态扩展算法以重建并复制到哈希表。