Java仮想マシンのスタックフレームスタック構造、各スタックフレームは独自のローカル変数テーブル、オペランドスタック、およびダイナミックリンクリターンアドレスおよび他の情報のための方法を有し、JVMの実装を可能に関連し、追加の情報、例えば、番組情報をデバッグするためのサポート。
1つのローカル変数テーブル
ローカル変数テーブルは、基本データ型(8種類)、オブジェクト参照、RETURNADDRESSタイプ。スロットは、従って、長い二つの二重スロット保存する必要があり、内部に32ビットのデータタイプを格納することができ、最小単位として可変スロットSLOT。のインデックス値nによってアクセスされたときの値を格納するn個のインデックス値とn + 1 2つのローカル変数を用いて、実際には、インデックスn型の値を倍、例えば、検索する小さいインデックス値を用いて、フレームスタックdoubleを見つけます。
Java仮想マシンのメソッド呼び出し渡されたパラメータを完了するために、ローカル変数テーブルを使用しました。クラスメソッド(静的クラスメソッド)を呼び出すときに、パラメータがゼロの連続した位置からローカル変数テーブルを順番に渡されます。(新しい)インスタンスメソッドを呼び出すときに、0番目のローカル変数は、参照(このキーワード)主題の例示的な方法を格納するために使用されなければなりません。
スペースを節約するために、スロットは、PCカウンタの値が変数のスコープを超えた場合に、再利用することができ、この変数に対応するスロットは、他の変数に渡すことができます。しかし、このような設計はまた、そのようなことはGCの挙動に影響を与えるなどの副作用を引き起こす可能性があります。次の質問:
質問:リサイクルヌルオブジェクトを設定することで表現することができますか?
この動作は、(大量のメモリを占有するオブジェクトは、長い時間のためのこの方法のスタックフレームは、メソッド呼び出しの数は、JITコンパイラ条件に到達し、リサイクルすることができない)特殊な状況下で非常に巧妙として使用することができます。通常、JITコンパイラの最適化後にnullを代入演算子を排除しますので、一般的に、あなたがnullを割り当てる必要はありません。
非アトミック合意longとdouble
64ビットのデータ・タイプの場合、JMMは比較的緩い要件を定義する:仮想マシンを分割すると、読み取りおよび書き込み操作は2つの32ビット演算に揮発性の64ビットのデータで変更されない可能が行われ、即ち、選択は、仮想マシンを可能にするために実装することができます64は、負荷のデータ型は、店舗、読みlongとdouble以外の原子協定でアトミック操作を、書くことを保証するものではありません。
複数のスレッドが変数を共有してある場合には、長いまたはダブルでvolatileとして宣言されていないされ、同時に、それらが読み取られ、操作を変更し、いくつかのスレッドはどちらの元の値にそれを読むかもしれないもこれは、値を変更するために、「半分変数」他のスレッドの値を表しています。
しかし、64ビットのデータ書き込み動作を選択するために、ほとんどすべての現在市販されている仮想マシンは、アトミックオペレーションとして処理され、従って、一般に、長い二重使用される場合、コードを記述する必要はありません具体的に揮発性として宣言します。
オペランドスタック2
スタックフレームを作成した場合は、オペランドスタックは空です。Java仮想マシンはまた、いくつかのオペランドスタックからのデータを除去するための命令、動作データ、及び提供し、オペランドスタックに定数または変数またはローカル変数テーブルのフィールドオブジェクトインスタンスの値からコピーするバイトコード命令の数を提供します操作は、新しいスタックを結果。オペランドスタックを調製するために使用されるメソッド呼び出しは、また、結果が返されるコールパラメータおよび方法を受けます。
オペランドスタックの各位置は、長い二重など、Java仮想マシンの定義に保存された値の任意のタイプであってもよいです。オペランドスタックは、スタックの深さによって決定されるスタック深さを有する、長い又は二重、2つのユニットを占有し、データユニットの他のタイプのスタックの深さを占めています。
データオペランドスタックが正しく、順次例えば、2ないint型のデータ・スタックを操作しなければならない、そして限りタイプを操作します。Java仮想マシン命令の小さな部分は、データオペランドの特定の種類に焦点を当てることができない、すべての裸のように動作するデータの種類の実行時のデータ領域のデータは、これらの命令は、元は解体することができないではない、データを変更するために使用することはできませんデータを分割し、これらの操作の精度は必須検査工程クラスファイルによって保証されます。
スタックフレームの重複領域、データの一部の一般的な方法は、追加の送信パラメータの割り当てなしに、都合のよいときに呼び出されます。
3ダイナミックリンク
現在のスタックフレームの各内部ポインタは、(直接参照に各ランの間に)ダイナミックリンクを実現するために、参照の実行時定数プールタイプの方法を含む、現在の方法のコード。
4メソッド呼び出し
4.1正常終了
プロセスの実行方法は、この方法が遭遇するとバイトコード命令は、通常の表現を返しました。戻り値のデータ型の種類に応じて、バイトコード命令の方法。この場合、正常に続行、戻り値の呼び出されたメソッドのスタックフレームでコールに発信者コードの後に、呼び出し側の責任、オペランドスタックを復元するために、現在のスタックフレームを前提としています。
4.2異常終了
仮想マシンまたは内部のバイトコード命令athrow経験が引き起こす場合、プロセスの実行方法は、Java仮想マシンが異常終了したことを示すために例外をスローします。
参考:「Java仮想マシン仕様(Java SEのバージョン8)「Java仮想マシン(第二版)、の深い理解」」。