Cose da Nerd

So tutto quello che riesco a sapere

Cose da Nerd

So tutto quello che riesco a sapere

PHP Fatal error: Out of memory

10/04/2021, 18:43

VirtualAlloc() failed: [0x000005af] Il file di paging è troppo piccolo per essere completato.

Se vi trovate davanti a questo codice di erore che cosa fate?
VirtualAlloc() failed: [0x000005af] Il file di paging è troppo piccolo per essere completato.
PHP Fatal error:  Out of memory (allocated 19312672768) (tried to allocate 45056 bytes) in Unknown on line 0
Fatal error: Out of memory (allocated 19312672768) (tried to allocate 45056 bytes) in Unknown on line 0
C:\xampp\php>

Il primo pensiero va al file di configurazione PHP.ini 
andiamo a verificare il parametro memory limit e lo impostiamo a -1
cosi lasciamo che PHP utilizzi tutta la memoria che gli serve.. 
Ma se andando a controllare il file vediamo che lo abbiamo già impostato?
ci viene in aiuto il fatto che Windows ci dice che il file di paging e troppo piccolo.. 
Quindi andiamo nelle proprietà del sistema operativo e verifichiamo la configurazione del file di paging.. ma anche li brutta sorpresa..  il file di paging è gestito dal sistema.. 
Quindi qual'è il problema?
Cercando nel cyber spazio finalmente trovo quello che mi serve:
https://bugs.php.net/bug.php?id=33595

troviamo il codice che genera l'errore:

class A {
    function __construct () {
        $this->b = new B($this);
    }
}


class B {
    function __construct ($parent = NULL) {
        $this->parent = $parent;
    }

}

for ($i = 0 ; $i < 1000000 ; $i++) {
    $a = new A();
   echo number_format(memory_get_usage());
}

fondamentalmente inizializzando una variabile di classe $a = new A(); all'interno di un ciclo PHP tiene in memoria le informazioni raggiungendo la saturazione della nostra RAM e del file di paging di Windows.
Quindi la soluzione inizializzare la variabile di classe fuori dal loop oppure creare un oggetto distruttore come da codice riportato in seguito:
class A {
    function __construct () {
        $this->b = new B($this);
    }
    function __destruct () {
        $this->b->__destruct();
    }
}

class B {
    function __construct ($parent = NULL) {
        $this->parent = $parent;
    }
    function __destruct () {
        unset($this->parent);
    }
}

for ($i = 0 ; $i < 1000000 ; $i++) {
    $a = new A();
    $a->__destruct();
echo number_format(memory_get_usage());
}

Problema risolto.
Procediamo con i lavori.. 
Ciao alla prossima!