Guida ai parametri JVM più importanti

1. Panoramica

In questo rapido tutorial, esploreremo le opzioni più note che possono essere utilizzate per configurare la Java Virtual Machine.

2. Memoria heap esplicita - Opzioni Xms e Xmx

Una delle pratiche più comuni relative alle prestazioni consiste nell'inizializzare la memoria heap secondo i requisiti dell'applicazione.

Ecco perché dovremmo specificare la dimensione dell'heap minima e massima. I seguenti parametri possono essere utilizzati per ottenerlo:

-Xms[unit] -Xmx[unit]

Qui, unit indica l'unità in cui la memoria (indicata dalla dimensione dell'heap ) deve essere inizializzata. Le unità possono essere contrassegnate come "g" per GB, "m" per MB e "k" per KB.

Ad esempio, se vogliamo assegnare minimo 2 GB e massimo 5 GB a JVM, dobbiamo scrivere:

-Xms2G -Xmx5G

A partire da Java 8, la dimensione di Metaspace non è definita. Una volta raggiunto il limite globale, JVM lo aumenta automaticamente, tuttavia, per superare qualsiasi instabilità non necessaria, possiamo impostare la dimensione di Metaspace con:

-XX:MaxMetaspaceSize=[unit]

Qui, la dimensione del metaspace indica la quantità di memoria che vogliamo assegnare a Metaspace .

Secondo le linee guida Oracle, dopo la memoria totale disponibile, il secondo fattore più influente è la proporzione dell'heap riservata alla Young Generation. Per impostazione predefinita, la dimensione minima di YG è 1310 MB e la dimensione massima è illimitata .

Possiamo assegnarli esplicitamente:

-XX:NewSize=[unit] -XX:MaxNewSize=[unit]

3. Raccolta dei rifiuti

Per una migliore stabilità dell'applicazione, la scelta del corretto algoritmo di Garbage Collection è fondamentale.

JVM ha quattro tipi di implementazioni GC :

  • Garbage Collector seriale
  • Garbage Collector parallelo
  • Garbage Collector CMS
  • G1 Garbage Collector

Queste implementazioni possono essere dichiarate con i seguenti parametri:

-XX:+UseSerialGC -XX:+UseParallelGC -XX:+USeParNewGC -XX:+UseG1GC

Maggiori dettagli sulle implementazioni di Garbage Collection possono essere trovati qui.

4. Registrazione GC

Per monitorare rigorosamente l'integrità dell'applicazione, dovremmo sempre controllare le prestazioni di Garbage Collection della JVM . Il modo più semplice per farlo è registrare l' attività del GC in un formato leggibile dall'uomo.

Utilizzando i seguenti parametri, possiamo registrare l' attività del GC :

-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles= -XX:GCLogFileSize=[ unit ] -Xloggc:/path/to/gc.log

UseGCLogFileRotation specifica la politica di scorrimento dei file di log, in modo molto simile a log4j, s4lj, ecc. NumberOfGCLogFiles indica il numero massimo di file di log che possono essere scritti per un singolo ciclo di vita dell'applicazione. GCLogFileSize specifica la dimensione massima del file. Infine, loggc indica la sua posizione.

È importante notare che sono disponibili altri due parametri JVM ( -XX: + PrintGCTimeStamps e -XX: + PrintGCDateStamps ) che possono essere utilizzati per stampare la data e l'ora nel registro GC .

Ad esempio, se si desidera assegnare un massimo di 100 file di registro GC , ciascuno con una dimensione massima di 50 MB e si desidera archiviarli nella posizione " / home / user / log /" , è possibile utilizzare la sintassi seguente:

-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=50M -Xloggc:/home/user/log/gc.log

Tuttavia, il problema è che un thread daemon aggiuntivo viene sempre utilizzato per monitorare l'ora del sistema in background. Questo comportamento può creare un collo di bottiglia delle prestazioni; ecco perché è sempre meglio non giocare con questo parametro in produzione.

5. Gestione della memoria

È molto comune per un'applicazione di grandi dimensioni affrontare un errore di memoria insufficiente che, a sua volta, provoca l'arresto anomalo dell'applicazione. È uno scenario molto critico e molto difficile da replicare per risolvere il problema.

Ecco perché JVM viene fornito con alcuni parametri che scaricano la memoria dell'heap in un file fisico che può essere utilizzato in seguito per scoprire le perdite:

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./java_pid.hprof -XX:OnOutOfMemoryError=";" -XX:+UseGCOverheadLimit

Un paio di punti da notare qui:

  • HeapDumpOnOutOfMemoryError indica alla JVM di eseguire il dump dell'heap nel file fisico in caso di OutOfMemoryError
  • HeapDumpPath indica il percorso in cui deve essere scritto il file; può essere fornito qualsiasi nome di file; tuttavia, se JVM trova un filetag nel nome, l'identificativo del processo corrente che causa l'errore di memoria insufficiente verrà aggiunto al nome del file con il formato .hprof
  • OnOutOfMemoryError è utilizzato per emettere comandi di emergenza da eseguire in caso di errore di memoria insufficiente; il comando corretto dovrebbe essere usato nello spazio di cmd args. Ad esempio, se vogliamo riavviare il server non appena si verifica l'esaurimento della memoria, possiamo impostare il parametro:
-XX:OnOutOfMemoryError="shutdown -r"
  • UseGCOverheadLimit è un criterio che limita la proporzione del tempo della VM trascorsa in GC prima chevenga generatounerrore OutOfMemory

6. 32/64 bit

Nell'ambiente del sistema operativo in cui sono installati entrambi i pacchetti a 32 e 64 bit, la JVM sceglie automaticamente i pacchetti ambientali a 32 bit.

Se vogliamo impostare manualmente l'ambiente a 64 bit, possiamo farlo utilizzando il parametro seguente:

-d

Il bit del sistema operativo può essere 32 o 64 . Maggiori informazioni su questo possono essere trovate qui.

7. Varie

  • -server : abilita “Server Hotspot VM”; questo parametro viene utilizzato per impostazione predefinita nella JVM a 64 bit
  • -XX: + UseStringDeduplication : Java 8u20 ha introdotto questo parametro JVM per ridurre l'uso non necessario della memoria creando troppe istanze della stessa stringa; questo ottimizza la memoria dell'heap riducendo ivalori String duplicatia un singolo array char [] globale
  • -XX: + UseLWPSynchronization : imposta lapolitica di sincronizzazione basata su LWP ( Light Weight Process ) invece della sincronizzazione basata su thread
  • -XX: LargePageSizeInBytes : imposta la dimensione della pagina grande utilizzata per l'heap Java; accetta l'argomento in GB / MB / KB; con pagine di dimensioni maggiori possiamo fare un uso migliore delle risorse hardware della memoria virtuale; tuttavia, ciò potrebbe causare dimensioni di spazio maggiori per PermGen , che a sua volta può forzare a ridurre le dimensioni dello spazio heap Java
  • -XX: MaxHeapFreeRatio : imposta la percentuale massima di heap libero dopo GC per evitare il restringimento.
  • -XX: MinHeapFreeRatio : imposta la percentuale minima di heap libero dopo GC per evitare l'espansione; per monitorare l'utilizzo dell'heap è possibile utilizzare VisualVM fornito con JDK.
  • -XX: SurvivorRatio : rapporto tra la dimensione dello spazio eden / sopravvissuto - ad esempio, -XX: SurvivorRatio = 6 imposta il rapporto tra ogni spazio dei sopravvissuti e lo spazio eden a 1: 6,
  • -XX: + UseLargePages : usa una grande memoria di pagina se è supportata dal sistema; si noti che OpenJDK 7 tende a bloccarsi se si utilizza questo parametro JVM

  • -XX: + UseStringCache : abilita la memorizzazione nella cache delle stringhe allocate comunemente disponibili nelpool di stringhe

  • -XX: + UseCompressedStrings : usa un tipo byte [] peroggetti String che possono essere rappresentati in puro formato ASCII
  • -XX: + OptimizeStringConcat : ottimizza leoperazioni di concatenazione di stringhe ove possibile

8. Conclusione

In questo rapido articolo, abbiamo appreso alcuni importanti parametri JVM, che possono essere utilizzati per ottimizzare e migliorare le prestazioni generali dell'applicazione.

Alcuni di questi possono essere utilizzati anche per scopi di debug.

Se desideri esplorare i parametri di riferimento in modo più dettagliato, puoi iniziare qui.