2014-05-23 45 views
11

Ho notato che java.util.HashMap produce rifiuti per il GC quando viene utilizzato sul mio sistema ad alte prestazioni, che in pratica è un selettore che legge dalla rete. Esiste un'alternativa a java.util.HashMap (vale a dire non è nemmeno necessario implementare java.util.Map, in altre parole, può avere una propria API) che posso usare che non lascerà spazzatura dietro?Esiste un'implementazione HashMap in Java che non produce dati inutili?


IMMONDIZIA = oggetti che vanno dalla portata e dovranno essere raccolti dal GC.


Per @ durron597:

public static void main(String[] args) { 

    Map<String, String> map = new HashMap<String, String>(); 

    while(true) { 

     map.put("foo1", "bah1"); 
     map.put("foo2", "bah2"); 

     map.remove("foo1"); 

     Iterator<String> iter = map.keySet().iterator(); 

     while(iter.hasNext()) { 
      iter.next(); 
     } 
    } 
} 

Ora familiare che con verbose: gc e vediamo cosa succede ... :)

+2

Cosa intendi con "spazzatura"? – durron597

+1

Garbage come nel comportamento di GC o nell'uso della memoria? O vuoi semplicemente sfrattare vecchie voci quando la memoria si esaurisce? – hexafraction

+0

@ durron597 garbage è oggetti non più in uso – Trilarion

risposta

5

Abbiamo anche scritto una raccolta di strutture di dati denominata CoralBits che offre prestazioni elevate con zero garbage creation. Riutilizza gli iteratori e gli oggetti di ingresso della mappa dei pool. Per le mappe che utilizzano le primitive come chiavi, abbiamo scritto IntMap e LongMap. Per una mappa generale abbiamo scritto PooledHashMap che implementa java.util.Map in modo da poter scambiare il codice con zero garbage.

Trove e Javolution sono altre alternative ma abbiamo trovato che Javolution crea spazzatura in alcune situazioni.

CoralBits fornisce anche una classe di strumentazione MemorySampler che è possibile utilizzare per scoprire dove vengono creati i rifiuti nel codice. Nel caso di un java.util.HashMap il colpevole è:

java.util.HashMap.createEntry(HashMap.java:901) 

Si può dare un'occhiata a this article scritto da me, che fornisce un esempio di come utilizzare MemorySampler per rilevare spazzatura nelle applicazioni.

Disclaimer: Sono uno degli sviluppatori di CoralBits.

+0

Come puoi dire la linea in cui viene creata la spazzatura? – JohnPristine

+0

La riga è la posizione in cui viene assegnato l'oggetto. Che diventi o meno spazzatura, è un'altra storia. Nel caso di 'java.util.HashMap' è rilasciato per il GC in modo che diventi davvero inutile. Usiamo '-javaagent' per eseguire questa strumentazione. – rdalmeida

9

Sì. Dai un'occhiata, ad es. allo Goldman Sachs collections.

Hanno una completa reimplementazione del framework di raccolta del JDK (e molto altro) con un'enfasi sul basso ingombro di memoria. Ad esempio, il loro HashMap non crea gli oggetti Entry finché non ne hanno davvero bisogno. Look at the documentation here.

C'è anche Javolution, una biblioteca più piccola con un obiettivo leggermente diverso - soprattutto per close-to-tempo reale e classi di tempo prevedibile, questo implica anche basso spazzatura.

Se si desidera memorizzare primitive (che evita la creazione dei loro involucri), guardare uno di questi:

  • Trove - le collezioni "standard" per le primitive
  • collezioni
  • di Goldman Sachs, di nuovo
  • HPPC - accesso di livello inferiore, spesso leggermente più veloce di Trove, ma consente di sparare più facilmente al piede
  • Koloboke - una forcella Trove realizzata da persone di OpenHFT. Incredibilmente veloce, in rapida evoluzione. A partire da ora (settembre 2014), solo le mappe e i set sono supportati.
+1

GS Collections è migrata alla Fondazione Eclipse ed ora è Eclipse Collections - http://www.eclipse.org/collections/ –

2

È possibile evitare un sacco di Garbage Collection se si memorizzano le voci della mappa off-heap. Ci sono una serie di librerie che possono aiutarvi in ​​questo:

+0

Questo può essere vero, ma dipende dai modelli di accesso in lettura e scrittura e dall'API della raccolta fuori heap. Nel percorso di lettura, alcune raccolte fuori heap possono produrre più abbandoni di oggetti e quindi rifiuti rispetto alle raccolte in heap, se deserializzano i dati fuori heap e creano nuove rappresentazioni di oggetti Java ogni volta che vengono letti i dati. Le raccolte on-heap possono evitarlo restituendo lo stesso oggetto che è già on-heap ogni volta. – npgall