Php 为什么全局$\u服务器阵列占用13倍的内存?

Php 为什么全局$\u服务器阵列占用13倍的内存?,php,memory-management,global-variables,Php,Memory Management,Global Variables,在使用普通PHP数组创建新数组(和元素)时,以下代码在PHP5.3中使用360字节,包括APC和APC。即使将元素添加到$\u GET,也只会使用304字节。但是,在$\u服务器中创建其他元素时,相同的代码使用4896字节 $mem = memory_get_usage(); //$array = array('HTTP_X_REQUESTED_WITH' => NULL); $_SERVER['HTTP_X_REQUESTED_WITH'] = NULL; //$_GET['HTTP_

在使用普通PHP数组创建新数组(和元素)时,以下代码在PHP5.3中使用360字节,包括APC和APC。即使将元素添加到$\u GET,也只会使用304字节。但是,在$\u服务器中创建其他元素时,相同的代码使用4896字节

$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>';
$mem=memory\u get\u usage();
//$array=array('HTTP\u X\u请求的\u带有'=>NULL);
$\u服务器['HTTP\u X\u请求的\u,带']=NULL;
//$\u GET['HTTP\u X\u REQUESTED\u WITH']=NULL;
打印(memory_get_usage()-$mem)。“bytes
”; 打印内存获取用法().“字节(进程)
”; 打印内存\u获取\u峰值\u使用率(真)。'字节(进程峰值)
; 打印(memory_get_usage()-$mem)。“bytes
”;

到底是什么原因导致$\u服务器阵列使用了如此多的额外内存?

如果我在PHP上开发,我不会担心这样的低级细节。可能发生的情况是,$\u服务器上的容量已达到限制,PHP必须创建一个新的哈希表,该哈希表的大小是当前哈希表的两倍。因为这些是有序关联的数组,所以哈希表的每个元素都会有相当大的开销,甚至是未填充的点

如果您对该过程的机制感兴趣,请参阅第418行


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

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

但是,当脚本启动时,$\u服务器、$\u请求、$\u发布、$\u获取和$\u环境超全局都是固定大小的。它们通常也不会被编辑(我不鼓励这样做)


它们很可能是用哈希表创建的,哈希表的大小刚好适合它们当前的大小。任何添加都会触发动态扩展算法重新构建并复制到哈希表。

5 KB的空值随机位置开销肯定值得注意。但是,如果哈希表是答案,也许我可以通过填充一个普通的PHP数组并观察内存使用情况来复制这个问题。是的,我会先转储$\u服务器的内容,然后使用您自己的副本进行测试。@Xeoncross:可能的话,$\u服务器、$\u GET、$\u POST和$\u请求超全局变量实际上是不可编辑的。你的物品很可能是用70个“物品”创建的,你唯一添加的物品可能会触发新尺寸的重建。@Mike:你不应该推断他在“担心”任何事情。这可能只是学术上的好奇心;我知道我很好奇。@hobodave:我想你应该把它作为一个回答