WeakHashMap e String Intern in java

Questo tipo di HashMap si differenza dalle altre perchè i riferimenti alle chiavi qui inseriti non sono di tipo strong, mentre lo sono per gli i valori e quindi, se all’interno dell’applicativo non esistono altri riferimenti alla chiave dell’entry questo è disponibile per il  garbage collector e lo stesso, di conseguenza vale per il valore.
Questo comportamento è molto utile nel caso in cui si vogliano implementare sistemi di cache, o comunque sistemi nei quali il valore nella mappa deve essere rimosso se non utilizzato / referenziato perchè ridurrà le possibilità di ottenere memory leak per un uso eccessivo o errato della mappa.
Bisogna però prestare attenzione quando si usano degli oggetti di tipo stringa come chiavi. Le stringhe di tipo letterale (literal) vengono internizzate, cioè poste in una area di memoria comune, in automatico dalla JVM e quindi, anche se poniamo l’oggetto a null questo non sarà collezionabile dal Garbage Collector perchè sarà ancora necessaria la sua presenza in memoria.

Per capire meglio cosa vuol dire internizzare possiamo analizzare il seguente esempio:

String a = “ciao io “;
String b = “sono davide”;
String uno = “ciao io sono davide”;
String due = a + b; // non è equivalente a “ciao io ” + “sono davide”
String tre = due.intern();
String quattro = new String(“ciao io sono davide”); //non è una stringa letterale

Le stringhe letterali (literal) sono internizzate in automatico dalla JVM, quindi lui ha internizzato: “ciao io “, “sono davide” e “ciao io sono davide” in spazi differenti di memoria. Il codice a  + b non sarà equivalente a “ciao io ” + “sono davide” perchè in questo modo all’atto della compilazione la jvm avrebbe rimosso la concatenazione creando una stringa unica e quindi avrebbe fatto puntare l’oggetto alla stessa posizione di memoria di  “ciao io sono davide” internizzato in precedenza. Se però vogliamo internizzare la stringa assegnata alla varibile “due” basta richiamare su questa il metodo intern(). Le stringhe internizzato sono molto utili perchè fanno risparmiare quantità di memoria al sistema riciclando allocazioni già avvenute in precedenza.

Quanto detto viene ancora di più evidenziato da un po’ di prove fatte qui di seguito:

System.out.println(“System.identityHashCode( uno ): ” + System.identityHashCode(uno));
System.out.println(“System.identityHashCode( due ): ” + System.identityHashCode(due));
System.out.println(“System.identityHashCode( tre ): ” + System.identityHashCode(tre));
System.out.println(“System.identityHashCode( quattro ): ” + System.identityHashCode(quattro));

System.out.println(“uno == due ” + (uno == due)); //FALSE
System.out.println(“uno == tre ” + (uno == tre)); //TRUE
System.out.println(“due == tre ” + (due == tre)); //FALSE
System.out.println(“uno == quattro ” + (uno == quattro)); //FALSE
System.out.println(“due == quattro ” + (due == quattro)); //FALSE
System.out.println(“tre == quattro ” + (tre == quattro)); //FALSE
System.out.println(“tre == quattro.intern() ” + (tre == quattro.intern())); //TRUE: perchè la stringa è stata internizzata

System.out.println(“uno.equals(due) ” + (uno.equals(due))); //TRUE
System.out.println(“due.equals(tre) ” + (due.equals(tre))); //TRUE
System.out.println(“uno.equals(tre) ” + (uno.equals(tre))); //TRUE
System.out.println(“uno.equals(quattro) ” + (uno.equals(quattro))); //TRUE
System.out.println(“due.equals(quatto) ” + (quattro.equals(quattro))); //TRUE
System.out.println(“tre.equals(quatto) ” + (uno.equals(quattro))); //TRUE

Quindi se alla nostra WeakHashMap inseriamo come chiavi stringhe internizzate queste non saranno mai collezionabili dal Garbage Collector e quindi l’utilizzo di questo oggetto perde di utilità.

Ed ora ecco alcuni links utili:

Una spiegazione dettagliata della WeakHashMap:

http://www.onjava.com/pub/a/onjava/2001/07/09/optimization.html

Qui trovate un esempio riguardante il mal funzionamento della WeakHashMap con le stringhe letterali:

http://java.dzone.com/articles/the-interesting-leak

Ed infine una spiegazione dettagliate sulla Weak Reference:

http://weblogs.java.net/blog/enicholas/archive/2006/05/understanding_w.html

Annunci

~ di jesty su giugno 23, 2008.

Una Risposta to “WeakHashMap e String Intern in java”

  1. […] WeakHashMap e String Intern in java nop! Scarica l'articolo in formato PDF […]

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

 
%d blogger hanno fatto clic su Mi Piace per questo: