2011-10-08 17 views
7

Avevo un problema di perdita di memoria in uno script Doctrine2 causato in parte da un pezzo di codice che avrebbe dovuto eliminare i problemi di memoria.Come chiudere correttamente un Entity Manager nella dottrina

Prima lo sapevo si potrebbe (e dovrebbe) cancellare l'Ente Gestore, ogni 20 iterazioni ho fatto la seguente:

if ($this->usersCalculated % 20 == 0) { 
    $this->em->close(); 
    $this->em = \Bootstrap::createEm(); 
    $this->loadRepositories(); 
} 

E il Bootstrap :: createEm assomiglia a questo:

public static function createEm() { 
    $em = EntityManager::create(Bootstrap::$connectionOptions, Bootstrap::$config); 
    $em->getConnection()->setCharset('utf8'); 
    return $em; 
} 

La ragione per cui ho ricreato l'Entity Manager in primo luogo era perché il mio UnitOfWork cresceva in modo selvaggio e non conoscevo il metodo $ em-> clear().

Quindi, anche se la perdita di memoria corrente sembra risolta al momento (o almeno ridotta), devo ancora creare un nuovo Entity Manager ogni volta che devo fare una query di inserimento/aggiornamento separata senza fare affidamento su qualcun altro il colore. Ad esempio, ogni volta che mando una e-mail, inserisco una riga nel database per indicare così, e il codice simile al seguente:

$emailSent = new \model\EmailSent(); 
    $emailSent->setStuff(); 
    // I do it in a new em to not affect whatever currentunit was doing. 
    $newEm = \Bootstrap::createEm(); 
    $newEm->persist($emailSent); 
    $newEm->flush(); 
    $newEm->close(); 

Da quello che ho imparato da prima, che lascia un po 'di memoria persa dietro.

Quindi la mia domanda è, cosa sto sbagliando qui? perché questa perdita di memoria e come dovrei davvero chiudere/ricreare un gestore di entità?

risposta

2

Hai provato a utilizzare effettivamente il metodo clear anziché chiudere?

Spero che questo ti aiuta --->Batch Processing

+0

@Cristian_Douce Come ho detto nella domanda, il mio problema di perdita di memoria è stato risolto dopo aver usato il chiaro invece di ricreare. Ma la domanda è ancora valida perché ho altre parti degli script che richiedono la creazione e la distruzione della em. –

+0

E che dire della pulizia prima di chiuderla? –

+0

@Cristian_Douce Sto svuotandolo prima di chiuderlo. E ho letto il codice delle dottrine per la funzione close, tutto ciò che fa è chiamare clear e contrassegnarlo come closed. Ci deve essere un certo attributo statico o un oggetto persistente che contiene un riferimento al em, se non il garbage collector lo avrebbe rilasciato. –

9

Hai provato:

$this->em->getConnection()->getConfiguration()->setSQLLogger(null); 

Ho letto che questo disattiva la SQL Logger che non viene cancellato e talvolta produce perdite di memoria come stai vivendo.

+1

Questo è quello! – Burgi

Problemi correlati