Java Heap Space Memory con l'API Runtime

1. Panoramica

In questo articolo, discuteremo le API fornite da Java che possono aiutarci a comprendere i diversi aspetti relativi allo spazio heap Java.

Ciò può essere utile per comprendere lo stato corrente della memoria della JVM e per esternalizzarla a servizi di monitoraggio come StatsD e Datadog, che possono quindi essere configurati per intraprendere azioni preventive ed evitare errori dell'applicazione.

2. Accesso ai parametri di memoria

Ogni applicazione Java ha una singola istanza di java.lang.Runtime che può aiutarci a comprendere lo stato di memoria corrente dell'applicazione. Il metodo statico Runtime # getRuntime può essere chiamato per ottenere l' istanza di Runtime singleton .

2.1. Memoria totale

Il metodo Runtime # getTotalMemory restituisce lo spazio heap totale attualmente riservato dalla JVM in byte. Include la memoria riservata agli oggetti attuali e futuri. Pertanto, non è garantito che sia costante durante l'esecuzione del programma poiché lo spazio heap Java può essere espanso o ridotto man mano che vengono allocati più oggetti.

Inoltre, questo valore non è necessariamente ciò che è in uso o la memoria massima disponibile.

2.2. Memoria libera

Il metodo Runtime # freeMemory restituisce lo spazio libero disponibile per le nuove allocazioni di oggetti in byte. Può aumentare a seguito di un'operazione di garbage collection in cui è disponibile più memoria libera dopo.

2.3. Memoria massima

Il metodo Runtime # maxMemory restituisce la memoria massima che JVM tenterà di utilizzare. Una volta che l'utilizzo della memoria JVM raggiunge questo valore, non allocherà più memoria e, al contrario, eseguirà la Garbage Collection più frequentemente.

Se gli oggetti JVM necessitano ancora di più memoria anche dopo l'esecuzione del Garbage Collector, la JVM potrebbe generare un'eccezione di runtime java.lang.OutOfMemoryErro .

3. Esempio

Nell'esempio seguente, inizializziamo un ArrayList e aggiungiamo elementi ad esso tenendo traccia dello spazio heap JVM utilizzando i tre metodi precedenti:

ArrayList arrayList = new ArrayList(); System.out.println("i \t Free Memory \t Total Memory \t Max Memory"); for (int i = 0; i < 1000000; i++) { arrayList.add(i); System.out.println(i + " \t " + Runtime.getRuntime().freeMemory() + " \t \t " + Runtime.getRuntime().totalMemory() + " \t \t " + Runtime.getRuntime().maxMemory()); } // ...
Output: i Free Memory Total Memory Max Memory 0 254741016 257425408 3817865216 1 254741016 257425408 3817865216 ... 1498 254741016 257425408 3817865216 1499 253398840 257425408 3817865216 1500 253398840 257425408 3817865216 ... 900079 179608120 260046848 3817865216 900080 302140152 324534272 3817865216 900081 302140152 324534272 3817865216 ...
  • Riga 1498: Il valore Runtime # freeMemory diminuisce quando viene allocato spazio sufficiente nell'heap Java.
  • Riga 900080: a questo punto, la JVM ha più spazio disponibile poiché GC è stato eseguito, quindi i valori di Runtime # freeMemory e Runtime # totalMemory aumentano.

I valori mostrati sopra dovrebbero essere diversi a ogni esecuzione di un'applicazione Java.

4. Personalizzazione dei parametri di memoria

Possiamo sovrascrivere i valori predefiniti per i parametri di memoria JVM impostando valori personalizzati su determinati flag durante l'esecuzione del nostro programma Java al fine di ottenere le prestazioni di memoria richieste:

  • -Xms: il valore assegnato al flag -Xms imposta il valore iniziale e minimo dell'heap Java. Può essere utilizzato nei casi in cui la nostra applicazione richiede più memoria rispetto al minimo predefinito all'avvio della JVM
  • -Xmx: Allo stesso modo, possiamo impostare il valore massimo per lo spazio heap assegnandolo al flag -Xmx . Può essere utilizzato quando vogliamo limitare la quantità di memoria che la nostra applicazione utilizzerà, di proposito.

Si noti inoltre che il valore -Xms deve essere uguale o inferiore al valore -Xmx .

4.1. Utilizzo

java -Xms32M -Xmx64M Main Free Memory : 31792664 bytes Total Memory : 32505856 bytes Max Memory : 59768832 bytes java -Xms64M -Xmx64M Main Free Memory : 63480640 bytes Total Memory : 64487424 bytes Max Memory : 64487424 bytes java -Xms64M -Xmx32M Main Error occurred during initialization of VM Initial heap size set to a larger value than the maximum heap size

5. conclusione

In questo articolo, abbiamo visto come recuperare le metriche di memoria JVM tramite la classe Runtime . Questi metodi possono essere utili quando si esaminano le perdite di memoria JVM e altri problemi relativi alle prestazioni della memoria JVM.

Abbiamo anche mostrato come assegnare valori personalizzati per determinati flag che portano a diversi comportamenti della memoria JVM per diversi scenari.