ヒープ内のオブジェクトを移動する際にJVMを容易にローカル変数、静的参照、クラスインスタンスまたはオブジェクト・アレイ・インスタンスの参照を更新することができます。しかし、どのようにそれは、オペランドスタックにプッシュの参照を更新することができますか?
ローカル変数とオペランドスタック内のエントリの間には根本的な違いはありません。どちらも、同じスタックフレームに住んでいます。どちらも正式に宣言されていないとの両方が彼らの実際の使用を認識するために推論を実行するJVMを必要としています。
次のコード
public static void example() {
{
int foo = 42;
}
{
Object bar = "text";
}
{
long x = 100L;
}
{
Object foo, bar = new Object();
}
}
(一般的に)にコンパイルされます
public static void example();
Code:
0: bipush 42
2: istore_0
3: ldc #1 // String text
5: astore_0
6: ldc2_w #2 // long 100l
9: lstore_0
10: new #4 // class java/lang/Object
13: dup
14: invokespecial #5 // Method java/lang/Object."<init>":()V
17: astore_1
18: return
インデックスのローカル変数に注意してください0
スタックフレームでは、さまざまな種類の値を使用して再割り当てされます。ボーナスとして、変数のインデックスへの最後の店は、1
インデックスの変数を無効にし0
、それはそれ以外のダングリング半分含んでいるでしょうとしてlong
価値を。
ローカル変数の型についての追加のヒントは、コードが枝が含まれている場合、オプションとスタックマップテーブルのみが存在しているデバッグ情報を、ありません。
ローカル変数参照を含むかどうかを決定するための唯一の方法は、プログラムフローに従って、命令の効果をたどることです。これは、すでにそれなしとして、私たちも知っているではないでしょう、オペランドスタック上の値を推測する意味するものではないstore
変数に命令プット。
検証は、それをしないそれも必須だし、JVMのガベージコレクタまたは任意のサポートコードがあまりにもそれを行うことができます。実装も検証であろう第1の解析の種類の情報を保持する単一の分析コードを有していてもよいです。
この情報は、ガベージコレクタがそれを必要とするたびに再構築された場合でもしかし、オーバーヘッドは天文学的ではないでしょう。ガベージコレクタは、定期的に実行され、それだけで現在実行方法については、この情報を必要とします。そして、その全てについてのみ実行を解釈しています。
JITコンパイラがコードを生成するとき、それは、とにかく種類の情報を利用する必要があり、ガベージコレクタのための情報を準備することができ、それが唯一と呼ばれる特定のポイントのためにそうしますsafepoints優れたガベージコレクションがあるのかどうか、コードのチェックを生成しました。これは、インの間でこれらの点は、データがガベージコレクタが理解し最適化されたコードは、それがそれらを処理している間、ガベージコレクタが再配置オブジェクトではないと仮定することができる形である必要はないことを意味します。
それはまた、すなわち、未使用の変数は存在しないかもしれない、コンパイルされた、最適化されたコードに到達可能性が実行を解釈簡単でより完全に異なるかもしれないことを意味し、それでもビューのソース・コード・ポイントから使用中のオブジェクトを最適化コードを用いて動作するときに未使用と考えることができますCPUレジスタに例えばそれぞれの分野のコピー、。