1. 概要

私たちの日常業務では、JVMの内部メモリ割り当てを気にしないことがよくあります。

ただし、 JVMメモリモデルの基本を理解していると、パフォーマンスの最適化とコード品質の向上に役立ちます

この記事では、静的メソッドとメンバーのJVMストレージについて説明します。

2. JVMのメモリ分類

静的メンバーのメモリ割り当てを深く掘り下げる前に、JVMのメモリ構造の理解を新たにする必要があります。

2.1. ヒープメモリ

ヒープメモリは、すべてのクラスインスタンスと配列にメモリを割り当てるためにすべてのJVMスレッド間で共有されるランタイムデータ領域です。

Javaは、ヒープメモリを若い世代と古い世代の2つのカテゴリに分類します。

JVMは、若い世代を内部的にエデンとサバイバースペースに分離します。 同様に、TenuredSpaceは旧世代の正式名称です。

ヒープメモリ内のオブジェクトのライフサイクルは、ガベージコレクタと呼ばれる自動メモリ管理システムによって管理されます。

したがって、ガベージコレクターは、オブジェクトの割り当てを自動的に解除するか、ヒープメモリのさまざまなセクションに移動することができます(若い世代から古い世代)。

2.2. 非ヒープメモリ

非ヒープメモリは、主にクラス構造、フィールド、メソッドデータ、およびメソッド/コンストラクターのコードを格納するメソッド領域で構成されます。

ヒープメモリと同様に、すべてのJVMスレッドはメソッド領域にアクセスできます。

パーマネントジェネレーション(PermGen)とも呼ばれるメソッド領域は、論理的にはヒープメモリの一部と見なされますが、JVMのより単純な実装では、ガベージコレクションを行わないことを選択できます。

ただし、 Java 8はPermGenスペースを削除し、Metaspaceという名前の新しいネイティブメモリスペースを導入します。

2.3. キャッシュメモリ

JVMは、JVM内部構造やJITコンパイラによって生成されたネイティブコードなどのネイティブコードのコンパイルと保存のためにキャッシュメモリ領域を予約します。

3. Java8より前の静的メンバーストレージ

Java 8より前では、PermGenは静的メソッドや静的変数のような静的メンバーを格納します。 さらに、PermGenはインターンされた文字列も格納します。

つまり、PermGenスペースには、変数とその技術値が格納されます。これらの値は、プリミティブまたは参照になります。

4. Java8以降の静的メンバーストレージ

すでに説明したように、PermGenスペースはJava8 でメタスペースに置き換えられ、静的メンバーのメモリ割り当てが変更されます。

Java 8以降、Metaspaceはクラスメタデータのみを格納し、ヒープメモリは静的メンバーを保持します。 さらに、ヒープメモリはインターンされた文字列のストレージも提供します。

5. 結論

この短い記事では、静的メンバーのJVMストレージについて説明しました。

まず、JVMのメモリモデルについて簡単に説明しました。 次に、Java8の前後の静的メンバーのJVMストレージについて説明しました。

簡単に言えば、静的メンバーはJava8より前のPermGenの一部であったことがわかります。 ただし、 Java 8以降、これらはヒープメモリの一部です。