Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Nota
I piani Basic, Standard ed Enterprise sono entrati in un periodo di ritiro il 17 marzo 2025. Per altre informazioni, vedere l'annuncio di ritiro di Azure Spring Apps.
Questo articolo si applica a:✅ Basic/Standard ❎ Enterprise
Questo articolo descrive vari concetti relativi alla gestione della memoria Java per comprendere il comportamento delle applicazioni Java ospitate in Azure Spring Apps.
Modello di memoria Java
La memoria di un'applicazione Java comprende diverse parti ed esistono diversi modi per dividerle. Questo articolo illustra la memoria Java divisa in memoria heap, memoria non heap e memoria diretta.
Memoria heap
La memoria heap archivia tutte le istanze di classe e le matrici. Ogni Java Virtual Machine (JVM) ha una sola area heap, condivisa tra i thread.
Spring Boot Actuator può osservare il valore della memoria heap. Spring Boot Actuator accetta il valore dell'heap come parte di jvm.memory.used/committed/max. Per altre informazioni, vedere la sezione jvm.memory.used/committed/max in Strumenti per risolvere i problemi di memoria.
La memoria heap è divisa in Young Generation e Old Generation. Questi termini sono descritti nell'elenco seguente, insieme ai termini correlati.
Young Generation: tutti i nuovi oggetti vengono allocati e invecchiati nella giovane generazione.
- Eden Space: in questo spazio vengono allocati i nuovi oggetti.
- Survivor Space: in questo spazio vengono spostati da Eden Space gli oggetti sopravvissuti a un ciclo di Garbage Collection. Survivor Space può essere diviso in due parti: s1 e s2.
Old Generation: anche detto Tenured Space. Gli oggetti rimasti in Survivor Space per un lungo periodo ti tempo verranno spostati in Old Generation.
Prima di Java 8, la memoria heap includeva anche un'altra sezione, denominata Permanent Generation. A partire da Java 8, la generazione permanente è stata sostituita dal metaspazio nella memoria al di fuori dell'heap.
Memoria non-heap
La memoria non heap è divisa nelle parti seguenti:
La parte della memoria non heap che ha sostituito la Permanent Generation (o permGen) a partire da Java 8. Spring Boot Actuator osserva questa sezione e la accetta come parte di
jvm.memory.used/committed/max. In altre parole,jvm.memory.used/committed/maxè la somma della memoria heap e della parte permGen precedente della memoria non heap. La generazione permanente precedente è composta dalle seguenti parti:- Metaspazio, che archivia le definizioni di classe caricate dai caricatori di classe.
- Spazio di classi compresse, destinato ai puntatori di classi compresse.
- Cache di codice, che archivia il codice nativo compilato da JIT.
Altri tipi di memoria, ad esempio lo stack di thread, che non vengono osservati da Spring Boot Actuator.
Memoria diretta
La memoria diretta è la memoria nativa allocata da java.nio.DirectByteBuffer, che viene usata in librerie di terze parti come nio e gzip.
Spring Boot Actuator non osserva il valore della memoria diretta.
Il diagramma seguente riepiloga il modello di memoria Java descritto nella sezione precedente.
Raccolta rifiuti di Java
Esistono tre termini relativi a Garbage Collection Java (GC): "GC minore", "GC maggiore" e "GC completo". Questi termini non sono chiaramente definiti nella specifica JVM. In questo articolo "GC principale" e "GC completo" vengono considerati equivalenti.
Il GC minore viene eseguito quando l'Eden space raggiunge la capacità massima. Rimuove tutti gli oggetti morti nella generazione giovane e sposta gli oggetti attivi dallo spazio Eden allo spazio s1 del spazio sopravvissuto oppure dal s1 al s2.
GC completo o GC maggiore esegue Garbage Collection nell'intero heap. GC completo può anche raccogliere parti come il metaspazio e la memoria diretta, che possono essere pulite solo da GC completo.
La dimensione massima dell'heap influisce sulla frequenza di GC minore e GC completo. Le dimensioni massime del metaspace e della memoria diretta influenzano il full GC.
Quando le dimensioni massime dell'heap vengono impostate su un valore minore, le operazioni di Garbage Collection vengono eseguite più frequentemente, rallentando leggermente l'app, ma limitando meglio l'utilizzo della memoria. Quando le dimensioni massime dell'heap vengono impostate su un valore maggiore, le operazioni di Garbage Collection vengono eseguite meno frequentemente, aumentando il rischio di memoria insufficiente. Per altre informazioni, vedere la sezione Tipi di problemi di memoria insufficiente di Problemi di riavvio delle app causati da problemi di memoria insufficiente.
Le parti metaspazio e memoria diretta possono essere raccolte solo da Full GC. Quando il metaspazio o la memoria diretta sono pieni, si verifica il full GC.
Configurazioni della memoria Java
Le sezioni seguenti descrivono aspetti importanti della configurazione della memoria Java.
Containerizzazione di Java
Le applicazioni in Azure Spring Apps vengono eseguite in ambienti contenitore. Per altre informazioni, vedere Inserire le applicazioni Java in contenitori.
Opzioni importanti di JVM
È possibile configurare le dimensioni massime di ogni parte della memoria usando le opzioni JVM. È possibile impostare le opzioni JVM usando i comandi dell'interfaccia della riga di comando di Azure o tramite il portale di Azure. Per altre informazioni, vedere la sezione Modificare le configurazioni per risolvere i problemi di Strumenti per risolvere i problemi di memoria.
L'elenco seguente offre una descrizione delle opzioni JVM:
Configurazione delle dimensioni dell'heap
-
-Xmsimposta le dimensioni iniziali dell'heap in base al valore assoluto. -
-Xmximposta le dimensioni massime dell'heap in base al valore assoluto. -
-XX:InitialRAMPercentageimposta le dimensioni iniziali dell'heap in base alla percentuale di dimensioni dell'heap/dimensioni della memoria dell'app. -
-XX:MaxRAMPercentageimposta le dimensioni massime dell'heap in base alla percentuale di dimensioni dell'heap/dimensioni della memoria dell'app.
-
Configurazione delle dimensioni della memoria diretta
-
-XX:MaxDirectMemorySizeimposta le dimensioni massime della memoria diretta in base al valore assoluto. Per altre informazioni, vedere MaxDirectMemorySize nella documentazione di Oracle.
-
Configurazione delle dimensioni del metaspazio
-
-XX:MaxMetaspaceSizeimposta le dimensioni massime del metaspazio in base al valore assoluto.
-
Dimensioni massime predefinite della memoria
Le sezioni seguenti descrivono come vengono impostate le dimensioni massime predefinite della memoria.
Dimensione massima predefinita dell'heap
Azure Spring Apps imposta le dimensioni massime predefinite della memoria heap su circa il 50%-80% della memoria dell'app per le app Java. In particolare, Azure Spring Apps usa le impostazioni seguenti:
- Se la memoria dell'app < 1 GB, le dimensioni massime predefinite dell'heap saranno pari al 50% della memoria dell'app.
- Se la memoria dell'app è compresa tra 1 GB < e < 2 GB, la dimensione massima predefinita dell'heap sarà pari al 60% della memoria dell'app.
- Se 2 GB <= la memoria dell'app < 3 GB, le dimensioni massime predefinite dell'heap saranno pari al 70% della memoria dell'app.
- Se la memoria dell'app è pari a 3 GB <, le dimensioni massime predefinite dell'heap saranno pari all'80% della memoria dell'app.
Dimensioni massime predefinite della memoria diretta
Quando le dimensioni massime della memoria diretta non vengono impostate tramite le opzioni JVM, JVM le imposta automaticamente sul valore restituito da Runtime.getRuntime.maxMemory(). Questo valore è approssimativamente uguale alle dimensioni massime della memoria heap. Per altre informazioni, vedere il file VM.java JDK 8.
Layout dell'utilizzo della memoria
Le dimensioni dell'heap sono influenzate dalla capacità di elaborazione. Essenzialmente, durante la configurazione è possibile mantenere le dimensioni massime predefinite dell'heap, il che lascia una quantità di memoria ragionevole per altre parti.
Le dimensioni del metaspazio dipendono dalla complessità del codice, ad esempio il numero di classi.
Le dimensioni della memoria diretta dipendono dalla velocità effettiva e dall'uso di librerie di terze parti, ad esempio nio e gzip.
L'elenco seguente descrive un tipico esempio di layout della memoria per le app da 2 GB. È possibile fare riferimento a questo elenco per configurare le impostazioni delle dimensioni della memoria.
- Memoria totale (2048 M)
- Memoria heap: Il parametro Xmx è 1433,6 M (70% della memoria di sistema). Il valore di riferimento dell'utilizzo giornaliero della memoria è 1200 M.
- Giovane generazione
- Spazio di Sopravvivenza (S0, S1)
- Eden Space
- Vecchia Generazione
- Giovane generazione
- Memoria non heap
- Parte osservata (osservata da Spring Boot Actuator)
- Metaspazio: il valore di riferimento di utilizzo giornaliero è 50 M-256 M
- Cache del codice
- Spazio di classi compresse
- Parte non osservata (da Spring Boot Actuator): il valore di riferimento di utilizzo giornaliero è 150 M-250 M.
- Stack di thread
- GC, simbolo interno e altro
- Parte osservata (osservata da Spring Boot Actuator)
- Memoria diretta: il valore di riferimento di utilizzo giornaliero è 10 M-200 M.
Il diagramma seguente mostra le stesse informazioni. I numeri in grigio sono i valori di riferimento dell'utilizzo giornaliero della memoria.
In generale, quando si configurano dimensioni massime della memoria, è consigliabile considerare l'utilizzo di ogni parte in memoria e la somma di tutte le dimensioni massime non deve superare la memoria totale disponibile.
Java memoria insufficiente (OOM)
OOM indica una condizione di memoria insufficiente per l'applicazione. Esistono due concetti diversi: OOM del contenitore e OOM della JVM. Per altre informazioni, vedere Problemi di riavvio delle app causati da problemi di memoria insufficiente.