実行時に各メソッドが消費するスタックメモリの量を調べようとしています。タスクを実行するには、私はちょうどm()
が呼び出された回数を私に言って整数を印刷StackOverflowError
、メソッドのスタックメモリをJavaで推測する
public class Main {
private static int i = 0;
public static void main(String[] args) {
try {
m();
} catch (StackOverflowError e) {
System.err.println(i);
}
}
private static void m() {
++i;
m();
}
}
を強制します。この簡単なプログラムを考案しました。私は手動で次の値を取得し、さまざまな値(128K、256K、384K)にJVMのスタックサイズ(-Xss
VMパラメータ)を設定しました:
stack i delta
128 1102
256 2723 1621
384 4367 1644
デルタは私が計算され、それが最後の値だましたラインの私と現在のもの。予想どおり、修正されています。そしてそこに問題がある。私が知っているように、スタックサイズのメモリの増分は128kであり、これは呼び出しごとに80byteのメモリ使用量(これは誇張されているようです)のようなものをもたらします。 BytecodeViewerの中m()
を見上げる
は、我々は、これは静的メソッドで、そこにはthis
パラメータ渡しはません、とm()
は引数を持っていないということを知っている2のスタックの最大の深さを取得します。また、戻りアドレスポインタも考慮する必要があります。だから、メソッド呼び出しごとに3 * 8 = 24バイトのようなものがなければなりません(私は変数あたり8バイトと仮定していますが、もちろんそれは完全にオフかもしれません)。それより少し上回っていても、48バイトと言うと、まだ80バイトの値から離れています。
私はメモリアラインメントと関係があると思っていましたが、その場合、約64または128バイトの値を持つことになります。
私は64ビットWindows7 OSで64ビットJVMを実行しています。
私はいくつかの前提を定めていますが、その中にはいくつかの理由があります。その場合、私はすべての耳です。
誰もが、私はこのI must be frank..
それはいくつかの洞察力のある情報でした。あなたはそれぞれのメソッド呼び出しが80バイトかかると思われる理由について理論化できますか? –
自分のJVM実装がFrame構造内でどのような情報を保持しているかを知ることができますか? – Jivings
@devouredelysium OpenJDKソースで私の答えを更新しました。 – Jivings