JVMローカル変数表
ローカル変数表はJVMスレッドスタックの各frameの中の一つの構成要素(詳細は「JVMスレッドスタック」を参照)であり、現在の方法の実行中でも依然として有効なローカル変数が格納されている。ローカル変数テーブルの長さはクラスコンパイル中に確定できます。これはframe初期化に有利です。
参考:https://blog.csdn.net/kevin_luan/articale/detail/22986081
void fun () {
int a = 0;
int b = 1;
int c = 2;
}
funの局所変数表長は4である(JVM仕様によると、最初はthisポインタ) void fun2() {
{
int a = 0;
}
int b = 1;
int c = 2;
}
funの局所変数表長は3であり、これは局所変数テーブル中のスロットビットが多重化されるからである。プログラムがb=1に到達すると、a変数の宣言周期は終了し、b変数はa変数の動作を占有します。SLot多重の特徴のために、面白い問題が出てきます。 public static void main(String[] args) throws Exception {
{
byte[] _64M = new byte[1024 * 1024 * 64];
}
System.gc();
Thread.sleep(1000);
System.gc();
Integer a = null;
System.gc();
}
-verbose:gcを使ってgcロゴを打ち上げると、次のように見えます。 [GC(System.gc() 67502 K->66452 K(123904 K)、0.0011957 secs) [Full GC(System.gc() 66452 K->66331 K(123904 K)、0.005344 secs) [GC(System.gc() 66987 K->66363 K(123904 K)、0.0007278 secs) [Full GC(System.gc() 66363 K->66331 K(123904 K)、0.005632 secs) [GC(System.gc() 66331 K->66331 K(123904 K)、0.0011248 secs) [Full GC(System.gc() 66331 K->795 K(123904 K)、0.005 secs) 初めてgcは64 Mの配列を回収しませんでしたが、_64 Mのライフサイクルはもう終わりました。1 s寝ても回収できません。スペースはそのまま1 sを占めました。 この現象を説明するのはJVM回収対象の条件から始まります。JVMは局所変数を回収する前提として、局部変数表にその対象の参照がない(配列エンティティがスタックしている)が、初めてgcを行った時、_64 Mオブジェクトは無効になりましたが、彼の参照はまだ部分変数テーブルにありますので、gcは回収できません。その後、勝手に一つの変数を宣言して、局部変数表の中の_を突き落としました。64 Mの引用はリサイクルすればいいです。 このような方法はいくつかのオープンソースコードの中にも見られます。オブジェクトのライフサイクルが終了し、方法内に時間がかかります。実際にJITコンパイルではnullの割り当て操作は消去されますが、JIT後のコードは正しく回収されます。このようなnullの割り当ては、JIT規格に達していないコール回数で効果があります。 参考:https://blog.csdn.net/kevin_luan/articale/detail/22986081