Come ha detto Stephen C, la perdita di memoria è dovuta ai classloader. Ma il problema è più acuto che a prima vista. Considerate questo:
mapkey --> class --> classloader --> all other classes defined by this classloader.
Inoltre,
class --> any static members, including static Maps e.g. caches.
Pochi tali cache statici possono iniziare ad aggiungere fino a gravi quantità di memoria persa ogni volta che una webapp o qualche altro modo dinamico (classloaded) app caricata è in bici.
Esistono diversi approcci per risolvere questo problema. Se non ti interessano le diverse "versioni" della stessa classe da diversi classloader, quindi semplicemente il tasto basato su Class.getName()
, che è un java.lang.String
.
Un'altra opzione è utilizzare java.util.WeakHashMap
. Questa forma di mappa mantiene solo i riferimenti deboli alle chiavi. I riferimenti deboli non reggono il GC, quindi la loro chiave non causerà un accumulo di memoria. Tuttavia, i valori sono non con riferimento debolmente. Quindi se i valori sono ad esempio istanze delle classi utilizzate come chiavi, lo WeakHashMap
non funziona.
fonte
2010-04-13 07:40:36
Non sono sicuro che causerebbe perdite di memoria ... significa solo che la versione statica di String (utilizzata dai suoi metodi statici) sarà referenziata dalla tua mappa. – Powerlord
I problemi di perdita di memoria sono (ad esempio) quando si appende un riferimento a un oggetto o una classe da una mappa di maggiore durata. Ad esempio, se in un'app Web si registra un driver JDBC dal proprio war (DriverManager.ergisterDriver), la classe DriverManager, caricata dal programma di caricamento del bootstrap (non dal classloader webapp), contiene un riferimento alla classe del driver. Pertanto, quando si scarica l'app Web, non è possibile scaricare il classloader webapp (a causa della classe di driver hooked) e nessuna delle altre classi di webapp viene scaricata. E non è carino – helios
Sarei curioso di sapere dove hai sentito questo concetto di perdita? Riesci a ricordare qualche dettaglio su dove hai sentito questo? Era forse nel contesto di un ambiente con più classloader (ad esempio, contenitore di app web)? –