2012-03-15 3 views
9

Sto eseguendo un'applicazione Java con una dimensione heap massima di 128 MB (-Xmx128M). Si sta eseguendo il completamento con esito positivo senza OutOfMemoryError o qualsiasi altra eccezione non gestita. Pertanto, presumo che la dimensione effettiva dell'heap rimanga all'interno del limite dichiarato di 128 MB.Perché l'utilizzo della memoria totale della mia JVM è più di 30 volte superiore al suo valore Xmx?

Tuttavia, osservando il processo per questa applicazione Java, sto vedendo un picco di utilizzo totale della memoria di 4.188.548 KB (~ 4 GB). Questa è una crescita di oltre 30 volte la dimensione massima controllata dell'heap. Sebbene comprenda che questo valore include la memoria virtuale allocata che può essere significativamente maggiore della memoria fisica utilizzata, influisce su limiti rigidi come quelli imposti da Sun Grid Engine e pertanto è significativo.

Com'è possibile? Comprendo che la memoria totale consumata dalla JVM include un po 'più della dimensione dell'heap, ma non capisco come potrebbe richiedere diversi GB di memoria extra oltre a ciò che l'applicazione ha effettivamente bisogno per creare i suoi oggetti ed eseguire il suo calcolo .

Sto utilizzando Sun Java 1.6.0.31, su una distribuzione Linux RHEL a 64 bit.

+2

Stai creando un numero illimitato di 'new Thread()' s? Ogni thread nativo che si genera ha una pila di memoria che non fa parte dell'heap java. – Affe

+0

Utilizzo della memoria in base a quale misura? Lo spazio degli indirizzi allocato che non ha un vero contenuto mappato ad esso probabilmente non è ciò che ti interessa; assicurati di misurare RSS, non VIRT. –

+0

@Affe Non si tratta di un problema di threading. L'applicazione è single-threaded. – jjcarver

risposta

4

Ci sono diversi pozzi di memoria oltre al heap Java controllata da -Xmx:

  • Discussione pile spazio
  • PermGen
  • diretta ByteBuffers e mappati ByteBuffer
  • memoria allocata da codice nativo/librerie

Senza conoscere i dettagli del tuo sistema direi, che qualcosa usa mappato ByteBuffers.

Tuttavia, è possibile esaminare il problema esaminando l'output del comando pmap. Elenca tutte le regioni di memoria del processo insieme ai nomi dei file a cui è associata una regione (se le regioni sono mappate ovviamente).

+1

Questo è un ottimo suggerimento, anche se nell'output pmap, purtroppo tutte le regioni di memoria gravemente offensive hanno una colonna "Mapping" di "anon", ad es. '000000052d4c0000 7722240 0 0 rw --- [anon]' – jjcarver

+0

Le regioni 'anon' riducono la lista sopra a" lib native "e a" direct ByteBuffers ". –

Problemi correlati