2010-12-08 55 views
4

當使用普通PHP數組創建新數組(和元素)時,以下代碼在PHP 5.3中使用360字節(帶和不帶APC)。即使向$ _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

邁克對PHP如何爲數組動態分配內部哈希表的解釋是現貨。對於動態分配數組,大小加倍是非常高效的。

但是,$ _SERVER,$ _REQUEST,$ _POST,$ _GET和$ _ENV superglobals在腳本啓動時都是固定大小。他們通常也沒有編輯(我勸阻它)。

它們很可能是用哈希表創建的,哈希表的大小足以適應其當前大小。然後任何添加都會觸發動態擴展算法來重建並複製到散列表。

4

如果我正在開發PHP,我不會擔心這樣的低級細節。可能發生的情況是,您已經達到了$ _SERVER的容量限制,並且PHP必須創建一個新的哈希表,其大小是當前哈希表的兩倍。由於這些是有序的關聯數組,所以哈希表中的每個元素都有相當大的開銷,即使是沒有填充的點。

如果你有興趣在這個過程中的機制,他們在zend_hash.c可用,線418

爲了驗證這一點,把你的$ _ SERVER的的var_dump然後把它在腳本中。 (1)對於php「動態數組」而言,實際上有不同的C代碼路徑,而對於php「哈希表」(它會爲你轉換它們),以及(2)問題可能在於將這麼多字符串複製到新的散列表中,以避免線程安全或指針開銷。

+0

對於NULL值隨機位置開銷5kb肯定值得注意。但是,如果散列表是答案,也許我可以通過填充一個普通的PHP數組並觀察內存使用情況來複制問題。 – Xeoncross 2010-12-08 03:06:32

相關問題