1. 概要

この記事では、Javaヒープスペースに関連するいくつかの側面を理解するのに役立つJavaによって提供されるAPIについて説明します。

これは、JVMの現在のメモリステータスを理解し、StatsDDatadogなどの監視サービスにアウトソーシングするのに役立ちます。これらのサービスは、プリエンプティブアクションを実行してアプリケーションを回避するように構成できます。失敗。

2. メモリパラメータへのアクセス

すべてのJavaアプリケーションには、 java.lang.Runtime の単一のインスタンスがあり、アプリケーションの現在のメモリステータスを理解するのに役立ちます。 Runtime#getRuntime staticメソッドを呼び出して、シングルトンRuntimeインスタンスを取得できます。

2.1. トータルメモリ

Runtime#getTotalMemory メソッドは、JVMによって現在予約されている合計ヒープスペースをバイト単位で返します。 現在および将来のオブジェクト用に予約されたメモリが含まれます。したがって、Javaヒープスペースは、より多くのオブジェクトが割り当てられると拡張または縮小される可能性があるため、プログラム実行中に一定であるとは限りません。

また、この値は、必ずしも使用中の値や使用可能な最大メモリではありません。

2.2. フリーメモリ

Runtime#freeMemory メソッドは、新しいオブジェクトの割り当てに使用できる空きヒープスペースをバイト単位で返します。 ガベージコレクション操作の結果として増加する可能性があり、その後、より多くの空きメモリが使用可能になります。

2.3. 最大メモリ

Runtime#maxMemory メソッドは、JVMが使用しようとする最大メモリを返します。 JVMのメモリ使用量がこの値に達すると、それ以上のメモリは割り当てられず、代わりにガベージコレクションが頻繁に行われます。

ガベージコレクタが実行された後でもJVMオブジェクトがさらに多くのメモリを必要とする場合、JVMは java.lang.OutOfMemoryErrorランタイム例外をスローする可能性があります。

3. 例

以下の例では、 ArrayList を初期化し、上記の3つの方法を使用してJVMヒープスペースを追跡しながら要素を追加します。

ArrayList<Integer> 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
...
  • 行1498: Runtime#freeMemory の値は、Javaヒープ内に十分なオブジェクトにスペースが割り当てられると減少します。
  • 行900080:この時点で、GCが実行されると、JVMに使用可能なスペースが増えるため、 Runtime#freeMemoryおよびRuntime#totalMemoryの値が増加します。

上記の値は、Javaアプリケーションを実行するたびに異なると予想されます。

4. メモリパラメータのカスタマイズ

必要なメモリパフォーマンスを実現するために、Javaプログラムの実行時にカスタム値を特定のフラグに設定することで、JVMメモリパラメータのデフォルト値を上書きできます。

  • -Xms: -Xms フラグに割り当てられた値は、Javaヒープの初期値と最小値を設定します。 これは、JVMの起動時にアプリケーションがデフォルトの最小値よりも多くのメモリを必要とする場合に使用できます。
  • -Xmx:同様に、 -Xmx フラグに割り当てることで、ヒープスペースの最大値を設定できます。 アプリケーションが意図的に使用するメモリの量を制限したい場合に使用できます。

-Xms の値は、-Xmxの値以下である必要があることにも注意してください。

4.1. 使用法

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. 結論

この記事では、Runtimeクラスを介してJVMメモリメトリックを取得する方法を見てきました。 これらのメソッドは、JVMメモリリークおよびその他のJVMメモリパフォーマンス関連の問題を調査するときに役立ちます。

また、特定のフラグにカスタム値を割り当てて、さまざまなシナリオでさまざまなJVMメモリの動作を実現する方法も示しました。