开发者

Why does the global $_SERVER array take 13x the memory?

开发者 https://www.devze.com 2023-01-29 15:13 出处:网络
When creating an new array (and element) using plain PHP arrays the following code uses 360 bytes in PHP 5.3 with and without APC. Even adding an element to $_GET only uses 304 bytes. However, when cr

When creating an new array (and element) using plain PHP arrays the following code uses 360 bytes in PHP 5.3 with and without APC. Even adding an element to $_GET only uses 304 bytes. However, when creating an additional element in $_SERVER the same code uses 4,896 bytes!

$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开发者_如何学JAVA(TRUE). ' bytes (process peak)<br>';
print (memory_get_usage() - $mem).' bytes<br>';

What in the world causes the $_SERVER array to use so much extra memory?


I wouldn't worry about low level details like that if I were developing on PHP. What's probably happening is that you've hit a capacity limit on $_SERVER, and PHP has to create a new hash table that is double the size of the current hash table. Since these are ordered associated arrays, there is a fairly large overhead cost to each element of the hash table, even spots that are not filled.

If you are interested in the mechanics of this process, they are available in zend_hash.c, line 418.

To test this, take a var_dump of your $_SERVER then put it in the script. Please be sure to not just test a dummy hash table for a couple reasons: (1) there are actually different C code paths for php "dynamic arrays" versus php "hash tables" (it converts them for you), and (2) the issue may be with copying so many strings over to the new hash table to avoid thread safety or the pointer overhead.


Mike's explanation of how PHP dynamically allocates the internal hash table for arrays is spot on. The doubling of size is very performant for dynamically allocating arrays.

However, the $_SERVER, $_REQUEST, $_POST, $_GET, and $_ENV superglobals are all of a fixed size when the script starts. They are also generally not edited (I discourage it).

It's very likely that they are created with hash tables that are just big enough to fit their current size. Any addition would then trigger the dynamic expansion algorithm to rebuild and copy to the hash table.

0

精彩评论

暂无评论...
验证码 换一张
取 消