Come viene diviso il pool di memoria Java?


224

Attualmente sto monitorando un'applicazione Java con jconsole. La scheda di memoria ti consente di scegliere tra:

Heap Memory Usage
Non-Heap Memory Usage
Memory Pool “Eden Space”
Memory Pool “Survivor Space”
Memory Pool “Tenured Gen”
Memory Pool “Code Cache”
Memory Pool “Perm Gen”

Qual'è la differenza tra loro ?


Supponendo che tu stia utilizzando Sun JDK, la migliore risposta sarà trovata nella loro documentazione: Tuning Garbage Collection (JDK 1.5) e Garbage Collection FAQ (JDK 1.4)
kdgregory

Risposte:


327

Memoria heap

La memoria heap è l'area dei dati di runtime da cui la VM Java alloca la memoria per tutte le istanze e gli array di classi. L'heap può avere dimensioni fisse o variabili. Il garbage collector è un sistema automatico di gestione della memoria che recupera la memoria heap per gli oggetti.

  • Eden Space : il pool dal quale la memoria è inizialmente allocata per la maggior parte degli oggetti.

  • Spazio sopravvissuto : la piscina contenente oggetti sopravvissuti alla raccolta dei rifiuti dello spazio Eden.

  • Tenured Generation o Old Gen : il pool contenente oggetti che esistono da tempo nello spazio dei sopravvissuti.

Memoria non heap

La memoria non heap include un'area del metodo condivisa tra tutti i thread e la memoria richiesta per l'elaborazione interna o l'ottimizzazione per la VM Java. Memorizza le strutture per classe come un pool di costanti di runtime, i dati di campo e di metodo e il codice per metodi e costruttori. L'area del metodo fa logicamente parte dell'heap ma, a seconda dell'implementazione, una VM Java potrebbe non essere garbage collection o compattarla. Come la memoria dell'heap, l'area del metodo può avere dimensioni fisse o variabili. La memoria per l'area del metodo non deve essere contigua.

  • Generazione permanente : il pool contenente tutti i dati riflettenti della macchina virtuale stessa, come oggetti classe e metodo. Con le macchine virtuali Java che utilizzano la condivisione dei dati di classe, questa generazione è suddivisa in aree di sola lettura e di lettura / scrittura.

  • Cache di codice : HotSpot Java VM include anche una cache di codice, contenente memoria utilizzata per la compilazione e l'archiviazione del codice nativo.

Ecco alcuni documenti su come usare Jconsole .


4
Non sono sicuro che @dfa sia completamente corretto, come afferma chiaramente la specifica della macchina virtuale Java: "Sebbene l'area del metodo sia logicamente parte dell'heap, le implementazioni semplici possono scegliere di non raccogliere la spazzatura o compattarla". Tuttavia è chiaro che jconsole mostra la cache di codice e la generazione permanente come non-heap, che sembra contraddire le specifiche. Qualcuno può fornire ulteriori chiarimenti su questa contraddizione?
James Bloom,

@JamesBloom - Mi chiedevo lo stesso. Anche se la definizione di base indica quale pool di memoria appartiene a quale tipo (heap / non-heap), potrebbe cambiare lo stato in modo esplicito?
Umang Desai,

2
il documento da cui questo è stato semestralmente sottratto : docs.intergral.com/pages/viewpage.action?pageId=22478944 Il documento contiene alcune altre buone informazioni sulla JVM, che vale la pena dare un'occhiata
Steve Siebert,

1
Nonostante molti voti positivi, in realtà non è una risposta così significativa. Ad esempio, cosa significano "oggetti sopravvissuti alla raccolta dei rifiuti dello spazio Eden"? Questi oggetti vengono spostati nello Spazio Sopravvissuto dall'Eden dopo essere sopravvissuti, o il loro spazio nell'Eden viene considerato come Spazio Sopravvissuto? E che dire della raccolta dei rifiuti in piscine diverse dallo spazio Eden, succede? Totalmente non chiaro.
Mikhail Batcer,

e non dimenticare lo stack (sul lato non heap) :)
Toothless Seer

70

La nuova parola chiave alloca memoria sull'heap Java. L'heap è il pool principale di memoria, accessibile a tutta l'applicazione. Se non è disponibile memoria sufficiente da allocare per quell'oggetto, la JVM tenta di recuperare parte della memoria dall'heap con una garbage collection. Se non è ancora possibile ottenere memoria sufficiente, viene generato un OutOfMemoryError e la JVM viene chiusa.

L'heap è suddiviso in diverse sezioni, chiamate generazioni. Poiché gli oggetti sopravvivono a più raccolte di rifiuti, vengono promossi in diverse generazioni. Le generazioni più anziane non vengono spazzate insieme così spesso. Poiché questi oggetti hanno già dimostrato di essere più a lungo vissuti, è meno probabile che vengano raccolti.

Quando gli oggetti vengono costruiti per la prima volta, vengono allocati nello spazio Eden. Se sopravvivono a una raccolta di rifiuti, vengono promossi nello Spazio Sopravvissuto e se vivono abbastanza a lungo lì, vengono assegnati alla Generazione di proprietà. Questa generazione di rifiuti viene raccolta molto meno frequentemente.

C'è anche una quarta generazione, chiamata Permanent Generation, o PermGen. Gli oggetti che risiedono qui non sono idonei per la garbage collection e di solito contengono uno stato immutabile necessario per l'esecuzione della JVM, come le definizioni di classe e il pool di costanti String. Si noti che lo spazio PermGen è progettato per essere rimosso da Java 8 e verrà sostituito con un nuovo spazio chiamato Metaspace, che verrà conservato nella memoria nativa. riferimento :http://www.programcreek.com/2013/04/jvm-run-time-data-areas/

inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine


Il diagramma sembra molto esplicativo ... È valido per qualsiasi algoritmo GC. G1 ha un set diverso.
Venkateswara Rao,

@Pythoner Penso che la bandiera in viola scuro dovrebbe essere -XX:PermSizee non -XX:MaxPermSizecome è già stato definito sopra.
Anurag


23

Java Heap Memory fa parte della memoria allocata a JVM dal sistema operativo.

Gli oggetti risiedono in un'area chiamata heap. L'heap viene creato all'avvio di JVM e può aumentare o diminuire di dimensioni durante l'esecuzione dell'applicazione. Quando l'heap si riempie, viene raccolta la spazzatura.

inserisci qui la descrizione dell'immagine

Puoi trovare maggiori dettagli su Eden Space, Survivor Space, Tenured Space e Permanent Generation nella seguente domanda SE:

Generazione Young, Tenured e Perm

PermGen è stato sostituito con Metaspace dalla versione Java 8.

Per quanto riguarda le tue domande:

  1. Eden Space, Survivor Space, Tenured Space fanno parte della memoria dell'heap
  2. Metaspace e Code Cache fanno parte della memoria non heap.

Codecache: Java Virtual Machine (JVM) genera codice nativo e lo memorizza in un'area di memoria chiamata codecache. JVM genera codice nativo per una serie di motivi, tra cui il ciclo di interpreti generato dinamicamente, gli stub JNI (Java Native Interface) e i metodi Java che vengono compilati in codice nativo dal compilatore just-in-time (JIT). Il JIT è di gran lunga il più grande utente del codecache.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.