Newsgroup: it.comp.java
Titolo: ...A proposito del garbage...!

...Bhč, io volevo solo inizializzare una discussione sul garbage collector
di java! Ne ho iniziata una in un post non mio,... non mi sembrava giusto...
ognuno dovrebbe trovare nel "suo" post delle info relative alla propria
domanda... per cui... !!!
Io il gc di Java lo ritengo una gran cosa... ma va "aiutato" in alcune
corcostanze di gestione particoilare della memoria come nella referenza
circolare...voi???
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

 circolare...voi???
Per quanto se ne diceva sul manuale di certificazione Java considera 
passibili di garbage collection gli oggetti quando non esiste più alcun 
percorso di reference tra essi e un qualunque thread di esecuzione (i 
thread sono considerati la root dell'albero di reference). Questa 
struttura ad albero elimina in partenza il problema dei riferimenti 
circolari: un oggetto (o gruppo di oggetti) è "raccoglibile" se e solo 
se non esiste un percorso di riferimenti tra esso e il thread, ovvero se 
è rimasto "isolato". I thread di per sè invece, proprio per la loro 
gestione particolare, diventano "raccoglibili" soltanto al termine della 
loro esecuzione. Immagino sia uno dei motivi per cui un thread terminato 
  non può essere rilanciato.
Il discorso poi è più complesso se prendiamo in esame i vari tipi di 
reference: strong reference, weak reference, phantom reference...
Basti dire che quello che si usa nella quasi totalità dei casi è il 
primo: una mano al gc (se proprio ci si tiene a dargliela anche se IMHO 
svolge già egregiamente il suo compito) la si potrebbe dare utilizzando 
correttamente i tipi di reference piuttosto che inventandosi tecniche di 
gc parallele.
Poi l'esperienza di ciascuno può anche essere diversa...
Ciao :)
pole

 circolare...voi???
Per il nulling, e' sufficiente capire quando un oggetto e' gc-able (come 
spiegato da Pole) e tutto va a posto da se' - i casi in cui e' necessario 
diventano immediatamente evidenti. A meno di non usare pattern 
"complicanti" (tipo singleton) - che vanno usati a ragion veduta proprio 
per le loro conseguenze - in genere non c'e' granche' da fare. 
Per il resto, io tendo ancora a limitare l'ordine di grandezza del numero 
di oggetti allocati (sia quel che sia, un certo overhead c'e', e se 
l'ordine di grandezza e' diverso mi aspetto diverse performance o almeno 
occupazione media di memoria, e quindi intervallo medio tra garbage 
collections).
Infine, c'e' da notare che la gc - al di fuori di un ambito tecnico - *ha* 
(puo' avere) un impatto visibile per l'utente. Per esempio, io uso TIBCO 
BusinessWork che e' un'applicazione gui internamente scritta in Java, e che 
e' piuttosto grossina (30Mb/100+Mb di core necessari). Per motivi vari, 
quell'installazione e' su una macchina deboluccia, e quando la JVM fa gc 
(si capisce perche' tra le altre cose la memoria usata/disponsibile e' 
continuamente mostrata) il software si blocca per un paio di secondi - 
noiossissimo.
-- 
You dont know what to do when you dont know what you're doing.
http://space.tin.it/computer/csadun


Per il punto 1 cito:
==> Explicit garbage collection <==
A third category where developers often mistakenly think they are 
helping the garbage collector is the use of System.gc(), which triggers 
a garbage collection (actually, it merely suggests that this might be a 
good time for a garbage collection). Unfortunately, System.gc() triggers 
a full collection, which includes tracing all live objects in the heap 
and sweeping and compacting the old generation. This can be a lot of 
work. In general, it is better to let the system decide when it needs to 
collect the heap, and whether or not to do a full collection. Most of 
the time, a minor collection will do the job. Worse, calls to 
System.gc() are often deeply buried where developers may be unaware of 
their presence, and where they might get triggered far more often than 
necessary. If you are concerned that your application might have hidden 
calls to System.gc() buried in libraries, you can invoke the JVM with 
the -XX:+DisableExplicitGC option to prevent calls to System.gc() and 
triggering a garbage collection.
Quindi, piuttosto che chiamare esplictamente il garbage collector,
fate invece il contrario: disabilitate le eventuali chiamate esplicite
che eventualmente ci siano utilizzando l'opzione
    -XX:+DisableExplicitGC
della Java Virtual Machine.
Per il punto 2 cito:
==> Explicit nulling <==
Explicit nulling is simply the practice of setting reference objects to 
null when you are finished with them. The idea behind nulling is that it 
assists the garbage collector by making objects unreachable earlier. Or 
at least that's the theory.
<...omissis...>
In the September 1997 "Java Developer Connection Tech Tips" column, Sun 
explained how explicit nulling was needed in very few special cases. 
Unfortunately, programmers often take this advice too far, using 
explicit nulling in the hope of helping the garbage collector. But in 
most cases, it doesn't help the garbage collector at all, and in some 
cases, it can actually hurt your program's performance.
Quindi, a parte pochissimi casi speciali veramente rari
(vedi l'articolo citato sopra per capire quali), NON è necessario
settare a null le variabili di tipo references
dopo che sono state usate.
Per il punto 3 analizza, se ne hai voglia,
il seguente programma giocattolo:
public class CircularList {
   private CircularList next;
   private CircularList prev;
   private int val;
   public int getVal() {return val;}
   public void setVal(int v) {val = v;}
   public CircularList(int v) {
     next = this;
     prev = this;
     setVal(v);
   }
   public void add(int v) {
     CircularList c = new CircularList(v);
     c.next = next;
     next.prev = c;
     c.prev = this;
     next = c;
   }
   public void remove() {
       prev.next = next;
       next.prev = prev;
       next = this;
       prev = this;
   }
}
public class CircularListTest {
   public CircularListTest(int len) {
     CircularList c = new CircularList(0);
     while(--len > 0)
       c.add(len);
   }
   public static void main(String[]args) {
     int len = -1;
     try {
       len = Integer.parseInt(args[0]);
     } catch(Exception e) {}
     if(len <= 0)
       System.out.println("Usage: java CircularListTest len");
     else {
       CircularListTest[]vect = new CircularListTest[1000];
       for(int i=0; true; i++) {
         if(i % vect.length == 0)
           System.out.println("Running "+ i);
         vect[i%vect.length] = new CircularListTest(len);
       }
     }
   }
}
Se invochi questo programma con:
    java CircularListTest 7500
esso comicerà a costruire infinite liste circolari
di 7500 elementi ciascuna tenendo memorizzate
sempre le ultime 1000 liste create in un vettore vect.
Se mandi in esecuzione questo programma esso continuerà forever
perché il gc da solo (senza che tu gli dica assolutamente nulla)
si preoccuperà di deallocare (quando ne ha bisogno)
le liste circolari precedenti alle ultime 1000.
Ad esempio al giro i = 9700 il gc sa che le prime 8700 liste
non sono più accessibili dal programma e quindi può liberare
i relativi 8700*7500 elementi che le compongono.
Quindi, riassumendo:
1. Il gc non va aiutato con System.gc().
2. Salvo rarissimi casi non occorre settare i reference a null.
3. Non esiste nessun problema per le strutture circolari.
- Dario

 circolare...voi???
Bhe.. io l'unica volta che ho avuto problemi di memory leak con java
e' stato un paio d'anni fa.. usando swing.. dovevo allocare a run
time nuove JLabel usarle per una frazione di secondo e quindi
crearne di nuove e cosi' via.. queste JLabel pero' dovevano
anche registrarsi nel framework degli eventi di swing..
Il risultato e' che dimenticare di deregistrare le JLabel come
listener degli eventi.. e anche se nella mia applicazione
non avevo piu' riferimenti a questi oggetti.. rimanevano
nel framework di swing.. bella gabola.. mi ci e' voluto un
profiler per capire perche' dopo pochi minuti di utilizzo
l'applicazione crashava con un outofmemoryexception.. hehehe
Da allora, faccio sempre attenzione a deregistrare anche
dal framework gli oggetti che non mi servono piu e che
sono dei Listener ;)
-- 
                Roberto Nunnari -software engineer-
                     mailto:
ro...@nunnisoft.ch
 
http://www.nunnisoft.ch
   Residenza Boschetto 12           tel/fax: 
+41-91-6046511
   6935 Bosco Luganese        """    mobile: 
+41-76-3208561
   Switzerland               (o o)
========================oOO==(_)==OOo========================