2013-12-10 28 views
16

Python gc.disable disabilita la garbage collection automatica. A quanto ho capito, ciò avrebbe alcuni effetti collaterali. Perché qualcuno dovrebbe voler disabilitare la raccolta automatica dei rifiuti e come si può gestire efficacemente la memoria senza di essa?Perché disabilitare il garbage collector?

risposta

16

Un uso per disabilitare il garbage collector è ottenere risultati più coerenti quando si cronometrano le prestazioni del codice. The timeit module fa questo.

def timeit(self, number=default_number): 
    if itertools: 
     it = itertools.repeat(None, number) 
    else: 
     it = [None] * number 
    gcold = gc.isenabled() 
    gc.disable() 
    ... 

In Python2 e fino a Python3.2gc.disable() viene utilizzato anche per evitare a bug caused by garbage collection occurring between fork and exec. Il problema sembra essere stato risolto in Python3.3 senza bisogno di chiamare gc.disable().

3

Un altro caso d'uso sarebbe controllare manualmente la raccolta dei rifiuti con gc.collect()

+0

Ma è necessario disabilitare il GC per poter utilizzare 'gc.collect()'? O che cosa è un caso d'uso per 'gc.collect()'? (nota: in passato avevo un caso di utilizzo simile in un'applicazione C# che era uscita dalla memoria su una casella <512MiB) –

+0

No. Puoi chiamare '' gc.collect() '' ogni volta che vuoi AFAIK. –

6

Dalla stessa pagina si collega a:

Dal collettore integra il conteggio di riferimento già utilizzati in Python, puoi disabilitare il raccoglitore se sei sicuro che il tuo programma non crei cicli di riferimento.

In modo che risponda alla seconda parte della domanda, "come si può gestire efficacemente la memoria senza di essa". Non creare cicli di riferimento. È un caso d'uso abbastanza limitato, certo.

Per la prima parte della domanda la risposta è la prestazione. Ancora una volta, un caso d'uso abbastanza limitato.

Disabilitare GC sarebbe di aiuto solo se (a) il GC sta effettivamente facendo il lavoro, e (b) il lavoro non sta ottenendo nulla, vale a dire che non trova nulla da liberare, o trova così poco che pensi che il tuo programma possa tollerare la perdita fino a quando GC è disabilitato. Quindi, se il tuo programma è troppo lento e non crea cicli di riferimento e la disattivazione di GC sembra velocizzarla, ti consigliamo di disabilitare GC.

Speculando (in base al GC precedente che ho visto, non in particolare a Python) che se non si alloca memoria, il garbage collector non avrà costi di prestazioni a lungo termine. Potrebbe avere dei costi a breve termine e imprevedibili che mettono in ordine ciò che è successo prima. Quindi, anche nel caso in cui stai entrando in una massiccia routine di calcolo dei numeri numpy e pensi che dovresti cercare di spremere tutte le possibili prestazioni da quella parte del codice, disabilitando GC mentre lo fai ancora non ti sarà d'aiuto. Ritarderà solo il costo del tempo di riordinare i cicli di riferimento precedenti fino a quando non riattiverai GC.

Probabilmente, i programmi eseguiti per un breve periodo e che non utilizzano molta memoria non necessitano della garbage collection, ma possono tollerare perdite. Ma ancor più discutibilmente, se inizi a pensare in questo modo finirai per avere dei problemi con un programma che perde più memoria di quanto ti aspettassi.

+0

Il problema è che, in pratica, è difficile (borderline impossibile) assicurarsi di non avere cicli di riferimento. Puoi facilmente assicurarti che il tuo codice non lo sia, ma per quanto riguarda le tue dipendenze? Poiché i moduli, le funzioni e le classi in genere non specificano se creano cicli di riferimenti, si dovrà passare attraverso il codice di ogni dipendenza dipendente e transitoria (inclusa la libreria standard) e verificare che non vengano fatti riferimenti di questo tipo. E, naturalmente, l'aggiornamento di una dipendenza potrebbe introdurre un ciclo. – Kevin

+0

@ Kevin: assolutamente. Penso che intendessi "abbastanza limitato" per essere un eufemismo ironico. –

5

Il problema con un GC abilitato è sempre che non si conosce quando si verifica. Quindi se (una parte del) il tuo programma è critico in termini di tempo, ha bisogno di tempo reale, ecc., Allora puoi disabilitare il GC per il tempo (quella parte) del tuo programma.

Se si desidera riattivare il GC automatico in un secondo momento o se si preferisce farlo manualmente chiamando lo gc.collect() non interessa a tale domanda.

Inoltre, alcuni programmi sono progettati per funzionare solo in un tempo molto breve, in modo che lo sviluppatore possa assicurare che non si possano verificare problemi di memoria durante questo periodo (considerare programmi come ls); quindi l'intero aspetto del GC può essere trascurato a favore delle prestazioni.

Problemi correlati