2016-03-23 23 views
10

Abbiamo un processo java in esecuzione su Solaris 10 che serve circa 200-300 utenti simultanei. Gli amministratori hanno riferito che la memoria utilizzata dal processo aumenta significativamente nel tempo. Raggiunge 2 GB in pochi giorni e non smette mai di crescere.La memoria del processo Java cresce indefinitamente. Perdita di memoria?

Abbiamo scaricato l'heap e l'abbiamo analizzato utilizzando Eclipse Memory Profiler, ma non siamo riusciti a vedere nulla fuori dall'ordinario. La dimensione dell'heap era molto piccola.

Dopo aver aggiunto la registrazione delle statistiche di memoria, alla nostra applicazione è stata riscontrata una discrepanza tra l'utilizzo della memoria riportato dall'utilità "top", utilizzata dall'amministratore e l'utilizzo riportato dalle librerie MemoryMXBean e Runtime.

Ecco un'uscita da entrambi.

Memory usage information 

From the Runtime library 
Free memory: 381MB 
Allocated memory: 74MB 
Max memory: 456MB 
Total free memory: 381MB 

From the MemoryMXBean library. 
Heap Committed: 136MB 
Heap Init: 64MB 
Heap Used: 74MB 
Heap Max: 456MB 
Non Heap Committed: 73MB 
Non Heap Init: 4MB 
Non Heap Used: 72MB 

Current idle threads: 4 
Current total threads: 13 
Current busy threads: 9 
Current queue size: 0 
Max threads: 200 
Min threads: 8 
Idle Timeout: 60000 

    PID USERNAME NLWP PRI NICE SIZE RES STATE TIME CPU COMMAND 
99802 axuser 115 59 0 2037M 1471M sleep 503:46 0.14% java 

Come può essere? il comando top riporta un uso molto più lungo. Mi aspettavo che RES dovesse essere vicino a heap + non-heap.

pmap -x, tuttavia, riporta la maggior parte della memoria nel mucchio:

Address  Kbytes  RSS  Anon  Locked Mode Mapped File 
*102000   56   56   56  - rwx---- [ heap ] 
*110000  3008  3008  2752  - rwx---- [ heap ] 
*400000 1622016 1621056 1167568  - rwx---- [ heap ] 
*000000  45056  45056  45056  - rw----- [ anon ] 

Qualcuno può far luce su questo? Sono completamente perso.

Grazie.

Aggiornamento

Questo non sembra essere un problema su Linux.

Inoltre, in base alla risposta di Peter Lawrey, l'"heap" riportato da pmap è un heap nativo non un heap Java.

+5

Esistono librerie native utilizzate in questa applicazione? – JimmyJames

+6

L'"heap" riportato da pmap è probabilmente l'heap nativo non l'heap Java. Quali risorse potrebbero essere utilizzate dall'applicazione nello spazio nativo? –

+0

Francamente, non ne sono sicuro. Abbiamo un server Jetty all'interno delle nostre chiamate REST di elaborazione delle applicazioni. A seconda della chiamata, è possibile eseguire select/insert/delete sul database usando ojdbc, o fare un po 'di I/O. Quindi la mia ipotesi è, sì, stiamo usando le librerie native, ma non sono sicuro di cosa siano? Esiste un elenco di librerie java native a cui posso fare riferimento? –

risposta

1

Negli ambienti di raccolta dei rifiuti, il mantenimento dei puntatori non utilizzati equivale a "mancata perdita" e impedisce al GC di eseguire il proprio lavoro. È davvero facile scrivere in modo casuale.

Un colpevole comune è hashtables. Un altro è array o vettori che sono cancellati logicamente (impostando l'indice di riutilizzo su 0) ma dove il contenuto effettivo di dell'array (sopra l'indice di utilizzo) sta ancora puntando a qualcosa.

+0

Non ciò che descrivi causa una perdita nell'heap? –

+3

La domanda originale indica che la dimensione dell'heap è (in qualche modo) stabile; è la dimensione della memoria "nativa" che sta aumentando. Questo mi suggerisce una fuga che non è correlata all'oggetto Java. Gli hashtables sono * non * il problema, qui, o si presenterebbero in un dump dell'heap che mostra molti oggetti Java attivi. –

+0

Buon punto. Le perdite che perdono risorse sono un probabile colpevole. Cose come file aperti ma non chiusi. Discussioni avviate ma non terminate. Alcuni tipi di archiviazione, come le classi, non sono affatto collezionabili. – ddyer