Java Heap Space Memory mit der Runtime API

1. Übersicht

In diesem Artikel werden die von Java bereitgestellten APIs erläutert, die uns helfen können, die verschiedenen Aspekte des Java-Heapspeichers zu verstehen.

Dies kann hilfreich sein, um den aktuellen Speicherstatus der JVM zu verstehen und an Überwachungsdienste wie StatsD und Datadog auszulagern, die dann so konfiguriert werden können, dass vorbeugende Maßnahmen ergriffen und Anwendungsfehler vermieden werden.

2. Zugriff auf Speicherparameter

Jede Java-Anwendung verfügt über eine einzelne Instanz von java.lang.Runtime , mit deren Hilfe wir den aktuellen Speicherstatus der Anwendung verstehen können. Die statische Methode Runtime # getRuntime kann aufgerufen werden, um die Singleton- Runtime- Instanz abzurufen .

2.1. Gesamtspeicher

Die Runtime # getTotalMemory- Methode gibt den gesamten von der JVM derzeit reservierten Heap-Speicherplatz in Byte zurück. Es enthält den für aktuelle und zukünftige Objekte reservierten Speicher. Daher kann nicht garantiert werden, dass es während der Programmausführung konstant ist, da der Java-Heap-Speicherplatz erweitert oder reduziert werden kann, wenn mehr Objekte zugewiesen werden.

Außerdem ist dieser Wert nicht unbedingt der verwendete Wert oder der maximal verfügbare Speicher.

2.2. Freier Speicher

Die Runtime # freeMemory- Methode gibt den freien Heapspeicherplatz zurück, der für die Zuweisung neuer Objekte in Bytes verfügbar ist. Sie kann sich aufgrund einer Speicherbereinigungsoperation erhöhen, bei der danach mehr freier Speicher verfügbar ist.

2.3. Maximaler Speicher

Die Runtime # maxMemory- Methode gibt den maximalen Speicher zurück, den die JVM zu verwenden versucht. Sobald die JVM-Speichernutzung diesen Wert erreicht, weist sie nicht mehr Speicher zu und sammelt stattdessen häufiger Müll.

Wenn die JVM-Objekte auch nach dem Ausführen des Garbage Collector noch mehr Speicher benötigen, löst die JVM möglicherweise eine Laufzeitausnahme java.lang.OutOfMemoryErro r aus.

3. Beispiel

Im folgenden Beispiel initialisieren wir eine ArrayList und fügen ihr Elemente hinzu, während wir den JVM-Heap-Speicher mit den oben genannten drei Methoden verfolgen:

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 ...
  • Zeile 1498: Der Wert für Runtime # freeMemory nimmt ab, wenn genügend Objekte im Java-Heap zugewiesen sind.
  • Zeile 900080: Zu diesem Zeitpunkt steht der JVM mehr Speicherplatz zur Verfügung, da GC ausgeführt wurde. Daher steigen die Werte für Runtime # freeMemory und Runtime # totalMemory .

Es wird erwartet, dass die oben gezeigten Werte bei jedem Lauf einer Java-Anwendung unterschiedlich sind.

4. Anpassen der Speicherparameter

Wir können die Standardwerte für die JVM-Speicherparameter überschreiben, indem wir beim Ausführen unseres Java-Programms benutzerdefinierte Werte auf bestimmte Flags setzen, um die erforderliche Speicherleistung zu erzielen:

  • -Xms: Der dem Flag -Xms zugewiesene Wert legt den Anfangs- und Mindestwert des Java-Heaps fest. Es kann in Fällen verwendet werden, in denen unsere Anwendung beim Starten der JVM mehr Speicher als das Standardminimum benötigt
  • -Xmx: Ebenso können wir den Maximalwert für den Heap-Speicherplatz festlegen, indem wir ihn dem Flag -Xmx zuweisen . Es kann verwendet werden, wenn wir die Speichermenge, die unsere Anwendung absichtlich verwendet, begrenzen möchten.

Bitte beachten Sie auch, dass der -Xms- Wert gleich oder kleiner als der -Xmx- Wert sein muss.

4.1. Verwendung

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. Schlussfolgerung

In diesem Artikel haben wir gesehen, wie JVM-Speichermetriken über die Runtime- Klasse abgerufen werden . Diese Methoden können hilfreich sein, wenn Sie JVM-Speicherlecks und andere Probleme im Zusammenhang mit der JVM-Speicherleistung untersuchen.

Wir haben auch gezeigt, wie benutzerdefinierte Werte für bestimmte Flags zugewiesen werden, die für verschiedene Szenarien zu unterschiedlichem JVM-Speicherverhalten führen.