Biagio Cosenza
blog
Archives - Previous posts

19 marzo 2006

Java, sfatiamo un mito: System.gc().

E' recentemente apparso un interessante articolo su JavaWorld. L'articolo, disponibile a questo link parla di come si possa incorrere in memory leaks in programmi java, problema di indubbio spessore soprattutto se parliamo di applicazioni J2EE.

Sembra strano sentir parlare di memory leaks in java. Infatti anche gli ambienti che forniscono una gestione automatica della memoria non sono immuni a questo problema.

Secondo l'articolo citato, in java, è quanto accade quando:
  1. vengono manenuti riferimenti ad oggetti sconosciuti o non voluti, impedendone la garbage collection
  2. esistono oggetti statici o oggetti dal ciclo di vita lungo, come gli oggetti di sessione
  3. avvengono dei fallimenti nella deallocazione di memoria in metodi nativi (in tal caso, l'errore può stare nel codice C++ sottostante)
  4. bugs nell'SDK o in librerie (cosa vera per alcune vecchie implementazioni delle AWT, ad esempio).
Qui occorre però fare alcune precisazioni. Anche se i memory leaks rappresentano un problema, probabilmente è più importante preoccuparsi dei resource leaks, spesso collegati ai primi. In un ambiente distribuito mantenere delle connessioni inattive è certamente più costoso di un qualunque memory leaks.
Inoltre i 3 e 4, per quanto plausibili, risultano poco probabili in un usuale ambito J2EE.

L'articolo prosegue con come identificare memory leaks, l'utilizzo di profiler ed una carrellata di esempi su dove è possibile migliorare la gestione della memoria.

Arrivando alle conclusioni, si legge quanto segue:
"Even those objects that could have been potentially garbage collected may actually stay in memory for a long time. So explicitly cleaning the heap may be a mandatory programming requirement in some applications; doing so must be considered on a case-by-case basis."
Ebbene, questa è una grossa falsità!

Ripulire esplicitamente l'heap forzando la garbage collection è una storia non nuova, ma comunque una falsità. Molti sostengono che System.gc() fa questo, ma non è così.
Se si fa una ricerca su Google su cosa questo metodo faccia, ci si accorgerà che i 2/3 delle pagine trovate afferma questo.

Il metodo System.gc() è un suggerimento, non un comando. E dopo tutto non dovrebbe davvero essere altrimenti, se si segue la filosofia del "don't care about memory management".

Una minima interazione con la garbage collection è possibile nella 5.0, ma anche in quel caso l'interazione è limitata a suggerire alla macchina virtuale quali politiche di garbage collection siano migliori in un caso specifico (ma si tratta difatto di un tuning della garbage collection, e non di un effettiva interazione a run time).
Cercare ottimizzazioni di questo tipo in un ambiente la cui filosofia è "nessuno gestisca la memoria!", significa marcarne immediatamente i limiti.

Ho commentato l'articolo su Artima, e concludo con la stessa frase:
this is a little loss of "don't care of memory management" philosophy