2010-12-08 4 views
4

Beim Erstellen eines neuen Arrays (und Elements) mit einfachen PHP-Arrays verwendet der folgende Code 360 ​​Bytes in PHP 5.3 mit und ohne APC. Selbst das Hinzufügen eines Elements zu $ ​​_GET verwendet nur 304 Bytes. Wenn Sie jedoch ein zusätzliches Element in $ _SERVER erstellen, verwendet derselbe Code 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(TRUE). ' bytes (process peak)<br>'; 
print (memory_get_usage() - $mem).' bytes<br>'; 

Was in der Welt bewirkt, dass das $ _SERVER-Array so viel zusätzlichen Speicher verwendet?

Antwort

2

Mikes Erklärung, wie PHP die interne Hash-Tabelle für Arrays dynamisch zuweist, ist genau richtig. Die Verdopplung der Größe ist sehr leistungsfähig für die dynamische Zuweisung von Arrays.

Die Superglobale $ _SERVER, $ _REQUEST, $ _POST, $ _GET und $ _ENV haben jedoch alle eine feste Größe, wenn das Skript gestartet wird. Sie werden auch im Allgemeinen nicht bearbeitet (ich entmutige es).

Es ist sehr wahrscheinlich, dass sie mit Hash-Tabellen erstellt werden, die gerade groß genug sind, um ihre aktuelle Größe anzupassen. Jede Hinzufügung würde dann den dynamischen Erweiterungsalgorithmus zum Neuaufbau und zum Kopieren in die Hash-Tabelle veranlassen.

4

Ich würde nicht über Low-Level-Details wie das, wenn ich auf PHP entwickeln würde. Wahrscheinlich haben Sie eine Kapazitätsgrenze für $ _SERVER erreicht, und PHP muss eine neue Hash-Tabelle erstellen, die doppelt so groß ist wie die aktuelle Hash-Tabelle. Da es sich um geordnete assoziierte Arrays handelt, gibt es für jedes Element der Hash-Tabelle ziemlich hohe Overhead-Kosten, sogar für Punkte, die nicht gefüllt sind.

Wenn Sie in der Mechanik dieses Prozesses interessiert sind, sie in zend_hash.c zur Verfügung stehen, Linie 418.

Um dies zu testen, eine var_dump Ihren $ _SERVER nehmen Sie es dann in dem Skript setzen. Bitte stellen Sie sicher, nicht nur eine Dummy-Hash-Tabelle aus mehreren Gründen zu testen: (1) Es gibt tatsächlich verschiedene C-Code-Pfade für PHP "dynamische Arrays" gegenüber PHP "Hash-Tabellen" (es konvertiert sie für Sie), und (2) Das Problem kann darin bestehen, dass so viele Strings in die neue Hash-Tabelle kopiert werden, um Thread-Sicherheit oder den Zeiger-Overhead zu vermeiden.

+0

5kb Overhead in zufälligen Orten für NULL-Werte ist sicherlich etwas zu beachten. Wenn jedoch die Hash-Tabelle die Antwort ist, kann ich das Problem möglicherweise durch das Auffüllen eines einfachen PHP-Arrays und die Überwachung der Speicherauslastung duplizieren. – Xeoncross

+0

Ja, ich würde zuerst den Inhalt von $ _SERVER ausgeben und zuerst mit Ihrer eigenen Kopie testen. –

+0

Ok, ich habe nur langsam ein Array erstellt und bei 8, 16, 32, 64 usw. zeigt das Array größere Speichersprünge von 128, 160, 224 und 352 Bytes. Dies addiert sich jedoch nicht, da mein Server-Array nur 70 Elemente enthält (also lange vor dem nächsten Sprung von 128 Elementen), aber für nur ein weiteres "NULL" -Element um mehr als 4 KB springt. – Xeoncross

Verwandte Themen