我想確定每個方法在運行時消耗多少堆棧內存。做任務,我已經設計了這個簡單的程序,只會迫使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();
}
}
打印整數告訴我m()
了多少次調用。我手動設置JVM的堆棧大小(-Xss
VM參數)不同的值(128K,256K,384K),獲得以下值:
stack i delta
128 1102
256 2723 1621
384 4367 1644
三角洲是由我計算,它的最後的值線我和現在的。如預期的那樣,它是固定的這就是問題所在。據我所知,棧大小的內存增量是128k,這可以產生類似於每個調用80byte的內存使用情況(這看起來很誇張)。
在BytecodeViewer中查找m()
,我們得到一個堆棧的最大深度爲2.我們知道這是一個靜態方法,並且沒有this
參數傳遞,並且m()
沒有參數。我們還必須考慮返回地址指針。所以應該有類似於每個方法調用的3 * 8 = 24個字節(我假設每個變量8個字節,這當然可能完全關閉,是嗎?)。即使比這還要多一點,比如說48bytes,我們仍然遠離80bytes的值。
我認爲這可能與內存對齊有關,但事實是,在這種情況下,我們會有大約64或128字節的值,我會說。
我在64位Windows7操作系統下運行64位JVM。
我做了幾個假設,其中一些可能完全關閉。既然如此,我就是耳朵。
在任何人開始問我爲什麼做這個I must be frank..
這是一些有見地的信息,先生。你可以理論化,爲什麼每個方法調用似乎需要80個字節? – 2012-02-26 00:53:31
我可以告訴你我自己的JVM實現在Frame結構中保存了什麼信息? – Jivings 2012-02-26 01:19:04
@devouredelysium用OpenJDK來源更新了我的答案。 – Jivings 2012-02-26 01:35:43