JVMアーキテクチャの説明
Jvm Architecture Explanation
翻訳元: https://dzone.com/articles/jvm-architecture-explained
すべてのJava開発者は、バイトコードが JRE (Javaランタイム環境)実行。しかし、多くの人はJREが Java仮想マシン (JVM)実装。バイトコードを解析し、コードを解釈して、最後に実行します。開発者は、JVMアーキテクチャを理解する必要があります。これにより、コードをより効率的に記述できるようになります。この記事では、JavaのJVMアーキテクチャとJVMのさまざまなコンポーネントについて詳しく見ていきます。
JVMとは何ですか?
仮想マシンは、物理コンピューターのソフトウェア実装です。 Javaは WORA( ライトワンスランエニウェア )。 開発のコンセプトの下で、それはにあります VM それでも僕らは走ります。沿って 翻訳者 Javaファイルのコンパイルをに変換します 。クラス ファイル、次に.classファイルをに入力します JVM 、.classファイルをロードして実行します。以下は、JVMのアーキテクチャ図です。
JVMアーキテクチャ図
JVMはどのように機能しますか?
上記のアーキテクチャ図に示されているように、JVMは3つの主要なサブシステムに分割されています。
- クラスローダーサブシステム
- ランタイムデータ領域
- 実行エンジン
クラスローダーサブシステム
Java 動的なクラスの読み込み この機能は、クラスローダーサブシステムによって処理されます。クラスファイルをロード、リンク、および初期化します。これは、コンパイル時ではなく、実行時にクラスが最初に参照されるときに行われます。
1.1ロード(ロード)
このコンポーネントはクラスをロードします。 BootStrapクラスローダー、Extensionクラスローダー、およびApplicationクラスローダーは、それを実装するのに役立つ3つのクラスローダーです。
- ブートストラップ ClassLoader -ブートストラップクラスパスからのクラスのロードのみを担当します rt.jar。 ローダーは最高の優先順位を受け取ります。
- 拡張クラスローダー -extフォルダの読み込みを担当します (jre lib)のクラス。
- アプリケーションクラスローダー- アプリケーションレベルのクラスパス、環境変数を参照するパスなどをロードする責任があります。
上記のクラスローダーは、クラスファイルをロードするときにデリゲート階層アルゴリズムに従います。
1.2リンク(リンク)。
- 検証 -バイトコードベリファイアは、生成されたバイトコードが正しいことを確認し、検証が失敗した場合、検証エラーを受け取ります。
- 準備ができました -すべての静的変数に対して、メモリが割り当てられ、デフォルト値が割り当てられます。
- 解決する -すべてのシンボルメモリ参照は、メソッド領域の元の参照に置き換えられます。
1.3初期化(初期化)。
これがクラス読み込みの最終段階です。これがすべてです 静的変数 生の値を割り当てて実行します 静的ブロック 。
2.ランタイムデータ領域-ランタイムデータエリア
ランタイムデータは、次の5つの主要コンポーネントに分かれています。
- メソッドエリア -静的変数を含むすべてのクラスレベルのデータがここに保存されます。各JVMには、共有リソースであるメソッド領域が1つだけあります。
- ヒープ領域 -すべてのオブジェクトとそれに対応するインスタンス変数および配列がここに格納されます。各JVMにはヒープ領域もあります。メソッド領域とヒープ領域は複数のスレッドのメモリを共有するため、保存されたデータはスレッドセーフではありません。
- スタックエリア -スレッドごとに、個別のランタイムスタックが作成されます。メソッド呼び出しごとに、スタックフレームと呼ばれるエントリがスタックメモリに作成されます。すべてのローカル変数はスタックメモリに作成されます。スタック領域は共有リソースではないため、スレッドセーフです。スタックフレームは、次の3つのサブエンティティに分割されます。
- ローカル変数配列 -メソッドに関連して、関与するローカル変数の数、対応する値がここに保存されます。
- オペランドスタック -中間操作を実行する必要がある場合、オペランドスタックは操作を実行するためのランタイムワークスペースとして機能します。
- フレームデータ -このメソッドは、このメソッドに対応するすべてのシンボルを格納します。いずれかで 異常な キャプチャブロック情報の場合、フレームデータに残ります。
- PCレジスタ -各スレッドには個別のPCレジスタがあります。命令が実行されると、現在実行中の命令のアドレスが維持され、PCレジスタが次の命令で更新されます。
- ネイティブメソッドスタック -ネイティブメソッドスタックは、ネイティブメソッド情報を保存します。スレッドごとに、個別のネイティブメソッドスタックが作成されます。
3.実行エンジン
に割り当てられた ランタイムデータ領域 バイトコードは実行エンジンによって実行されます。実行エンジンはバイトコードを読み取り、1つずつ実行します。
- 通訳 -インタプリタはバイトコードをより速く解釈しますが、実行は遅くなります。インタプリタの欠点は、メソッドが複数回呼び出されると、毎回新しい解釈が必要になることです。
- JITコンパイラ -JITコンパイラは、インタプリタの欠点を解消します。実行エンジンは、インタープリターの助けを借りてバイトコードを変換しますが、重複するコードが見つかると、JITコンパイラーを使用して、バイトコード全体をコンパイルしてネイティブコードに変更します。このネイティブコードは、システムパフォーマンスを向上させるために、繰り返されるメソッド呼び出しに直接使用されます。
- 中間コードジェネレータ -中間コードを生成します
- コードオプティマイザー -上記で生成された中間コードを最適化する責任があります
- ターゲットコードジェネレータ -マシンコードまたはネイティブコードの生成を担当します
- プロファイル -ホットスポットの検出を担当する特別なコンポーネント。つまり、メソッドが複数回呼び出されるかどうか。
- ガベージコレクター :参照されていないオブジェクトを収集して削除します。
System.gc()
を呼び出すことでガベージコレクションをトリガーできますが、実行が保証されるわけではありません。 JVMガベージコレクションは、作成されたオブジェクトを収集します。
Java Native Interface(JNI) :JNIは、ネイティブメソッドライブラリと対話し、エンジンの実行に必要なネイティブライブラリを提供します。
ネイティブメソッドライブラリ ネイティブメソッドライブラリ )。 :これは、実行エンジンに必要なネイティブライブラリのコレクションです。