Non è possibile calcolare retrospettivamente l'impronta esatta di una variabile poiché due variabili possono condividere lo stesso spazio allocato nella memoria
Proviamo a condividere la memoria tra due array, vediamo che allocare il secondo array costa metà della memoria del primo. Quando disinseriamo il primo, quasi tutta la memoria è ancora utilizzata dal secondo.
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)
Quindi non possiamo concludere che il secondo array utilizzi metà della memoria, poiché diventa falso quando disattiamo il primo.
Per una visione completa di come viene allocata la memoria in PHP e per quale utilizzo, ti consiglio di leggere il seguente articolo: Quanto sono veramente grandi gli array (e i valori) PHP? (Suggerimento: GRANDE!)
Le nozioni di base sul conteggio dei riferimenti nella documentazione PHP contengono anche molte informazioni sull'uso della memoria e i riferimenti contano per il segmento di dati condivisi.
Le diverse soluzioni qui esposte sono buone per le approssimazioni, ma nessuna può gestire la sottile gestione della memoria PHP.
- calcolo dello spazio appena assegnato
Se vuoi lo spazio appena assegnato dopo un compito, devi usarlo memory_get_usage()
prima e dopo l'assegnazione, poiché usarlo con una copia ti dà una visione errata della realtà.
// 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";
Ricorda che se vuoi memorizzare il risultato del primo memory_get_usage()
, la variabile deve già esistere prima, ememory_get_usage()
deve essere chiamata un'altra volta precedente, e anche ogni altra funzione.
Se si desidera eseguire l'eco come nell'esempio precedente, il buffer di output deve essere già aperto per evitare la memoria di contabilità necessaria per aprire il buffer di output.
- calcolo dello spazio richiesto
Se vuoi fare affidamento su una funzione per calcolare lo spazio richiesto per memorizzare una copia di una variabile, il seguente codice si occupa di diverse ottimizzazioni:
<?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
Notare che la dimensione del nome della variabile è importante nella memoria allocata.
- Controlla il tuo codice !!
Una variabile ha una dimensione di base definita dalla struttura C interna utilizzata nel codice sorgente PHP. Questa dimensione non fluttua nel caso dei numeri. Per le stringhe, aggiungerebbe la lunghezza della stringa.
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;
Se non teniamo conto dell'inizializzazione del nome della variabile, sappiamo già quanto usa una variabile (in caso di numeri e stringhe):
44 byte nel caso dei numeri
+ 24 byte nel caso di stringhe
+ la lunghezza della stringa (incluso il carattere finale NUL)
(questi numeri possono cambiare a seconda della versione PHP)
È necessario arrotondare per eccesso a un multiplo di 4 byte a causa dell'allineamento della memoria. Se la variabile si trova nello spazio globale (non all'interno di una funzione), allocherà anche 64 byte in più.
Quindi se vuoi usare uno dei codici all'interno di questa pagina, devi controllare che il risultato utilizzando alcuni semplici casi di test (stringhe o numeri) corrisponda a quei dati tenendo conto di ognuna delle indicazioni in questo post ($ _GLOBAL array, prima chiamata di funzione, buffer di output, ...)