Sie können den genauen Footprint einer Variablen nicht nachträglich berechnen, da zwei Variablen denselben zugewiesenen Speicherplatz im Speicher gemeinsam nutzen können
Versuchen wir, den Speicher zwischen zwei Arrays zu teilen. Wir sehen, dass das Zuweisen des zweiten Arrays die Hälfte des Speichers des ersten Arrays kostet. Wenn wir den ersten deaktivieren, wird fast der gesamte Speicher noch vom zweiten verwendet.
echo memory_get_usage()."\n"; // <-- 433200
$c=range(1,100);
echo memory_get_usage()."\n"; // <-- 444348 (+11148)
$d=array_slice($c, 1);
echo memory_get_usage()."\n"; // <-- 451040 (+6692)
unset($c);
echo memory_get_usage()."\n"; // <-- 444232 (-6808)
unset($d);
echo memory_get_usage()."\n"; // <-- 433200 (-11032)
Wir können also nicht schließen, dass das zweite Array die Hälfte des Speichers verwendet, da es falsch wird, wenn wir das erste deaktivieren.
Um einen vollständigen Überblick darüber zu erhalten, wie der Speicher in PHP zugewiesen wird und für welche Verwendung, empfehle ich Ihnen, den folgenden Artikel zu lesen: Wie groß sind PHP-Arrays (und -Werte) wirklich? (Hinweis: GROSS!)
Die Grundlagen der Referenzzählung in der PHP-Dokumentation enthalten auch viele Informationen zur Speichernutzung, und Referenzen zählen für gemeinsam genutzte Datensegmente.
Die verschiedenen hier vorgestellten Lösungen sind gut für Annäherungen, aber keine kann die subtile Verwaltung des PHP-Speichers bewältigen.
- Berechnung des neu zugewiesenen Speicherplatzes
Wenn Sie den neu zugewiesenen Speicherplatz nach einer Zuweisung verwenden möchten, müssen Sie ihn memory_get_usage()
vor und nach der Zuweisung verwenden, da die Verwendung mit einer Kopie eine fehlerhafte Ansicht der Realität ergibt.
// open output buffer
echo "Result: ";
// call every function once
range(1,1); memory_get_usage();
echo memory_get_usage()."\n";
$c=range(1,100);
echo memory_get_usage()."\n";
Denken Sie daran, dass, wenn Sie das Ergebnis des ersten speichern möchten memory_get_usage()
, die Variable bereits vorher vorhanden sein muss und ein memory_get_usage()
anderes vorheriges Mal aufgerufen werden muss, sowie jede andere Funktion auch.
Wenn Sie wie im obigen Beispiel Echo wiedergeben möchten, muss Ihr Ausgabepuffer bereits geöffnet sein, um zu vermeiden, dass der zum Öffnen des Ausgabepuffers erforderliche Abrechnungsspeicher benötigt wird.
- Berechnung des benötigten Platzes
Wenn Sie sich auf eine Funktion verlassen möchten, um den erforderlichen Speicherplatz zum Speichern einer Kopie einer Variablen zu berechnen, werden im folgenden Code verschiedene Optimierungen vorgenommen:
<?php
function getMemorySize($value) {
// existing variable with integer value so that the next line
// does not add memory consumption when initiating $start variable
$start=1;
$start=memory_get_usage();
// json functions return less bytes consumptions than serialize
$tmp=json_decode(json_encode($value));
return memory_get_usage() - $start;
}
// open the output buffer, and calls the function one first time
echo ".\n";
getMemorySize(NULL);
// test inside a function in order to not care about memory used
// by the addition of the variable name to the $_GLOBAL array
function test() {
// call the function name once
range(1,1);
// we will compare the two values (see comment above about initialization of $start)
$start=1;
$start=memory_get_usage();
$c=range(1,100);
echo memory_get_usage()-$start."\n";
echo getMemorySize($c)."\n";
}
test();
// same result, this works fine.
// 11044
// 11044
Beachten Sie, dass die Größe des Variablennamens im zugewiesenen Speicher von Bedeutung ist.
- Überprüfen Sie Ihren Code!
Eine Variable hat eine Grundgröße, die durch die im PHP-Quellcode verwendete innere C-Struktur definiert wird. Diese Größe schwankt bei Zahlen nicht. Bei Zeichenfolgen wird die Länge der Zeichenfolge hinzugefügt.
typedef union _zvalue_value {
long lval; /* long value */
double dval; /* double value */
struct {
char *val;
int len;
} str;
HashTable *ht; /* hash table value */
zend_object_value obj;
} zvalue_value;
Wenn wir die Initialisierung des Variablennamens nicht berücksichtigen, wissen wir bereits, wie viel eine Variable verwendet (bei Zahlen und Zeichenfolgen):
44 Bytes bei Zahlen
+ 24 Bytes bei Strings
+ die Länge der Zeichenfolge (einschließlich des letzten NUL-Zeichens)
(Diese Zahlen können sich je nach PHP-Version ändern.)
Aufgrund der Speicherausrichtung müssen Sie auf ein Vielfaches von 4 Bytes aufrunden. Befindet sich die Variable im globalen Bereich (nicht innerhalb einer Funktion), werden 64 weitere Bytes zugewiesen.
Wenn Sie also einen der Codes auf dieser Seite verwenden möchten, müssen Sie anhand einiger einfacher Testfälle (Zeichenfolgen oder Zahlen) überprüfen, ob das Ergebnis mit diesen Daten übereinstimmt, wobei alle Angaben in diesem Beitrag berücksichtigt werden ($ _GLOBAL-Array, erster Funktionsaufruf, Ausgabepuffer, ...)