2. Quali aree sono contenute nell'area dei dati runtime?
3. Quali dati vengono archiviati rispettivamente nello stack e nell'heap?
4. Perché dovremmo sostituire la generazione permanente (PermGen) con il metaspazio (MetaSpace)?
5. Comprendi la struttura di base dello spazio heap? In quali circostanze un oggetto entrerà nella vecchia generazione?
6. In quale area di memoria vengono posizionati gli oggetti di grandi dimensioni?
7. Qual è il processo di creazione degli oggetti Java?
Domanda risposta
1. Da quali parti è composta la JVM?
Risposta: JVM è un eseguibilecodice byte (.class) computer virtuale con file, che fornisce anche la gestione della memoria, la raccolta dei rifiuti e altri meccanismi. Contiene le seguenti parti principali.
Sottosistema di caricamento della classe: responsabile del caricamento dei file bytecode (.class) nella JVM.
Area dati runtime: è l'area di memoria utilizzata dalla JVM durante l'esecuzione.
Motore di esecuzione: responsabile dell'interpretazione o della compilazione del bytecode in codice macchina per l'esecuzione del processore.
Interfaccia della libreria nativa: fornisce una serie di API per chiamare librerie native scritte nel sistema operativo o in altri linguaggi.
2. Quali aree sono contenute nell'area dei dati runtime?
Risposta: L'area dati runtime è l'area di memoria allocata dalla JVM durante l'esecuzione di un programma Java.
Contatore del programma: è un piccolo spazio di memoria ed è l'indirizzo dell'istruzione bytecode attualmente eseguita dal thread. Se il thread sta eseguendo un metodo nativo, il valore di questo contatore non è definito.
Stack di macchina virtuale Java: ogni thread creerà uno stack di macchina virtuale al momento della creazione, che viene utilizzato per archiviare la tabella delle variabili locali del thread, il frame degli operandi, il collegamento dinamico, le informazioni sull'uscita del metodo, ecc. Lo stack della macchina virtuale Java contiene più stack frame. Il processo da ciascun metodo chiamato al completamento dell'esecuzione corrisponde al processo dall'inserimento di uno stack frame nello stack nella macchina virtuale.
Stack di metodi nativi: è lo spazio preparato dalla JVM per eseguire metodi nativi. Ha funzioni simili allo stack della macchina virtuale Java. È un modello di memoria che descrive il processo di esecuzione dei metodi nativi.
Heap: utilizzato per archiviare quasi tutte le istanze e gli array di oggetti ed è l'area principale in cui funziona il garbage collector.
Area del metodo: utilizzata per archiviare informazioni sulla classe, costanti, variabili statiche, codice compilato dal compilatore just-in-time, ecc. caricato dalla JVM. Prima di JDK1.8, era implementato come generazione permanente. A partire da JDK1.8, la generazione permanente viene sostituita dallo spazio originale. Metaspace utilizza la memoria locale anziché la memoria heap.
3. Quali dati vengono archiviati rispettivamente nello stack e nell'heap?
Risposta: dati archiviati nello stack (stack della macchina virtuale Java):
Tabella delle variabili locali: utilizzata principalmente per memorizzare parametri del metodo e variabili locali all'interno del metodo. I tipi di dati includono tipi di dati di base e riferimenti a oggetti.
Stack di operandi: utilizzato per memorizzare temporaneamente istruzioni operative e risultati intermedi durante l'esecuzione del metodo.
Collegamento dinamico: un riferimento al pool costante della classe a cui appartiene il metodo, utilizzato per risolvere i riferimenti ai simboli nel metodo.
Indirizzo di ritorno del metodo: memorizza l'indirizzo della successiva istruzione eseguita dopo la chiamata del metodo. Dati archiviati nell'heap:
Istanza dell'oggetto: un'istanza dell'oggetto creata tramite la parola chiave new nel programma, incluse le proprietà e i metodi dell'oggetto.
Array: tutti i tipi di array, inclusi gli array di tipo base e gli array di oggetti.
4. Perché dovremmo sostituire la generazione permanente (PermGen) con il metaspazio (MetaSpace)?
Risposta: Sostituire la generazione permanente con metaspazio serve principalmente a risolvere alcuni problemi e limiti intrinseci della generazione permanente e a migliorare le prestazioni e la flessibilità della JVM.
Migliorare la flessibilità e l'efficienza della gestione della memoria: la dimensione della memoria della generazione permanente viene impostata all'avvio della JVM e non può essere regolata dinamicamente. Metaspace utilizza la memoria locale invece della memoria heap Java e la sua dimensione può essere regolata dinamicamente secondo necessità.
Risolvi il problema dello scarico delle classi e della raccolta dei rifiuti: il comportamento GC della generazione permanente è complesso e imprevedibile e l'efficienza del riciclo è bassa.
Fornire prestazioni e stabilità migliori: l'utilizzo del metaspazio rende la gestione della memoria JVM più unificata e coerente, poiché il metaspazio, come altre aree di memoria, viene gestito utilizzando la memoria locale. Ciò semplifica le strategie di gestione della memoria e migliora le prestazioni e la stabilità complessive.
Semplifica la gestione della memoria JVM
5. Comprendi la struttura di base dello spazio heap? In quali circostanze un oggetto entrerà nella vecchia generazione?
Risposta: La struttura di base dello spazio heap è composta principalmente dalla nuova generazione, dalla vecchia generazione e dalla generazione permanente. Dopo JDK8, la generazione permanente viene sostituita dal metaspazio e utilizza la memoria locale per l'archiviazione.
Generazione Cenozoica: Il progresso della nuova generazione è suddiviso nell'area Eden e due aree sopravvissuti (Survivor 0 e Survivor 1)
Area dell'Eden: gli oggetti appena creati allocano prima la memoria nell'area dell'Eden.
Area superstite (S0, S1): utilizzata per immagazzinare oggetti sopravvissuti alla garbage collection di nuova generazione. Dopo ogni GC minore, gli oggetti sopravvissuti verranno copiati avanti e indietro tra queste due aree.
Vecchia generazione: oggetti che sono ancora vivi dopo più GC minori. La raccolta dei rifiuti (Major GC o Full GC) viene eseguita meno frequentemente nella vecchia generazione.
Generazione/metaspazio permanente: utilizzato per archiviare metadati di classi, incluse definizioni di classi, costanti, variabili statiche, codice compilato just-in-time, ecc.
La situazione in cui l'oggetto è nella vecchia generazione:
Viene raggiunta la soglia di età: ogni oggetto ha un'età quando la memoria viene allocata nella nuova generazione e l'età verrà aumentata di 1 dopo ogni GC minore. Quando l'età raggiunge una certa soglia (il valore predefinito è 15), l'oggetto verrà promosso alla vecchia generazione.
Oggetto grande: se l'oggetto è troppo grande e supera la soglia impostata dalla JVM, l'oggetto allocherà direttamente lo spazio nella vecchia generazione.
Spazio insufficiente nell'area dei sopravvissuti: se l'area dei sopravvissuti non ha spazio sufficiente per ospitare tutti gli oggetti sopravvissuti durante il GC minore, questi oggetti verranno
Determinazione dinamica dell'età degli oggetti: se la dimensione di tutti gli oggetti della stessa età nello spazio Sopravvissuto supera la metà dello spazio Sopravvissuto, allora gli oggetti la cui età è maggiore o uguale a questa età possono entrare direttamente nella vecchia generazione.
// 动态年龄计算代码
uint ageTable::compute_tenuring_threshold(size_t survivor_capacity){//survivor_capacity是survivor空间的大小size_t desired_survivor_size =(size_t)((((double) survivor_capacity)*TargetSurvivorRatio)/100);//TargetSurvivorRatio 为50size_t total =0;
uint age =1;while(age < table_size){
total += sizes[age];//sizes数组是每个年龄段对象大小if(total > desired_survivor_size)break;
age++;}
uint result = age < MaxTenuringThreshold ? age : MaxTenuringThreshold;...}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
6. In quale area di memoria vengono posizionati gli oggetti di grandi dimensioni?
Risposta: Gli oggetti di grandi dimensioni (array e stringhe molto grandi) vengono solitamente allocati direttamente nell'area di memoria della vecchia generazione.Questo per evitare che la nuova generazione si esibisca frequentementeRaccolta dei rifiutiIn questo momento, oggetti di grandi dimensioni vengono spesso copiati tra l'area Eden e l'area Survivor, migliorando così l'efficienza della raccolta dei rifiuti. Configura la soglia affinché gli oggetti di grandi dimensioni entrino direttamente nella vecchia generazione:
7. Qual è il processo di creazione degli oggetti Java?
risposta:
Controllo del caricamento delle lezioni
Se la classe non è stata caricata, connessa e inizializzata, la JVM caricherà prima la classe. Ciò include i seguenti passaggi:
Caricamento: leggere il file della classe tramite il caricatore della classe e caricare il bytecode della classe in memoria.
Connessione: prevede tre fasi: verifica, preparazione e parsing. Verificare la correttezza dei file di classe, preparare variabili statiche della classe, allocare memoria e risolvere i riferimenti ai simboli in riferimenti diretti.
Inizializzazione: esegue il blocco di inizializzazione statica della classe e l'inizializzazione delle variabili statiche.
allocazione della memoria
JVM alloca memoria per i nuovi oggetti nell'heap. La dimensione della memoria allocata è determinata dalla struttura dell'oggetto, inclusa l'intestazione dell'oggetto e i dati dell'istanza.
La JVM ha due modi principali per allocare la memoria:
Bump-the-pointer: se la memoria heap è regolare, il puntatore di allocazione deve solo spostarsi di una distanza specifica nell'area di memoria libera.
Elenco libero: se la memoria heap è irregolare, la JVM deve mantenere un elenco libero e trovare il blocco appropriato dall'elenco libero durante l'allocazione della memoria.
inizializzare al valore zero
La JVM inizializzerà tutte le variabili di istanza dell'oggetto sui rispettivi valori predefiniti. Ad esempio, le variabili di tipo numerico verranno inizializzate su 0, le variabili di tipo booleano su false e le variabili di tipo di riferimento su null.
Imposta l'intestazione dell'oggetto
Imposta le informazioni sull'intestazione dell'oggetto nello spazio di memoria dell'oggetto, che include il codice hash dell'oggetto, l'età di generazione del GC, il flag di stato del blocco, il blocco mantenuto dal thread, l'ID del thread distorto, ecc.
Inizializzazione del costruttore
Chiama il costruttore dell'oggetto per completare l'inizializzazione dell'oggetto. Ciò include l'esecuzione di operazioni di inizializzazione esplicite sulle variabili di istanza e sul codice nel corpo del costruttore. I passaggi specifici sono i seguenti:
Esegue il blocco di inizializzazione dell'istanza della classe.
Esegui il metodo di costruzione della classe genitore dall'alto al basso secondo la gerarchia di ereditarietà.
Inizializza le variabili di istanza su valori specificati esplicitamente.
Esegui la parte principale del metodo di costruzione della classe.