3 回答
TA貢獻1797條經驗 獲得超6個贊
觀察到的行為受到HotSpot優化器的影響,但這不是唯一的原因。當我運行以下代碼
public static void main(String[] argv) {
System.out.println(System.getProperty("java.version"));
System.out.println(countDepth());
System.out.println(countDepth());
System.out.println(countDepth());
System.out.println(countDepth());
System.out.println(countDepth());
System.out.println(countDepth());
System.out.println(countDepth());
}
static int countDepth() {
try { return 1+countDepth(); }
catch(StackOverflowError err) { return 0; }
}
啟用JIT后,我得到如下結果:
> f:\Software\jdk1.8.0_40beta02\bin\java -Xss68k -server -cp build\classes X
1.8.0_40-ea
2097
4195
4195
4195
12587
12587
12587
> f:\Software\jdk1.8.0_40beta02\bin\java -Xss68k -server -cp build\classes X
1.8.0_40-ea
2095
4193
4193
4193
12579
12579
12579
> f:\Software\jdk1.8.0_40beta02\bin\java -Xss68k -server -cp build\classes X
1.8.0_40-ea
2087
4177
4177
12529
12529
12529
12529
在這里,JIT的效果清晰可見,顯然,優化后的代碼需要更少的堆??臻g,并且它表明啟用了分層編譯(實際上,-XX:-TieredCompilation如果程序運行時間足夠長,則使用一次跳轉)。
相反,在禁用JIT的情況下,我得到以下結果:
> f:\Software\jdk1.8.0_40beta02\bin\java -Xss68k -server -Xint -cp build\classes X
1.8.0_40-ea
2104
2104
2104
2104
2104
2104
2104
> f:\Software\jdk1.8.0_40beta02\bin\java -Xss68k -server -Xint -cp build\classes X
1.8.0_40-ea
2076
2076
2076
2076
2076
2076
2076
> f:\Software\jdk1.8.0_40beta02\bin\java -Xss68k -server -Xint -cp build\classes X
1.8.0_40-ea
2105
2105
2105
2105
2105
2105
2105
這些值仍會變化,但不會在單個運行時線程內變化,并且幅度較小。
因此,如果優化程序可以減少每次方法調用所需的堆??臻g(例如,由于內聯),則存在(相當小的)差異,該差異會變得更大。
是什么導致這種差異?我不知道這個JVM是如何做到的,但是一種情況可能是強制執行堆棧限制的方式要求對堆棧結束地址進行一定的對齊(例如,匹配內存頁面大?。?,而內存分配返回的內存具有一個起始地址,對齊保證較弱。將這種情況與ASLR結合使用,可能在對齊要求的大小范圍內始終存在差異。
TA貢獻1842條經驗 獲得超22個贊
它的過時,但你可以嘗試Thread.countStackFrames()像
public static int levelsDeep() {
return Thread.currentThread().countStackFrames();
}
根據Javadoc,
不推薦使用。此調用的定義取決于suspend()已棄用的。此外,此調用的結果從未明確定義。
計算此線程中的堆棧幀數。線程必須被掛起。
至于為什么您觀察到不確定性行為,我只能假設它是JIT和垃圾收集器的某種組合。
TA貢獻1851條經驗 獲得超4個贊
您無需捕獲異常,只需創建一個如下所示的異常:
新的Throwable()。getStackTrace()
要么:
Thread.currentThread()。getStackTrace()
由于JVM實現是特定的,因此它仍然很笨拙。JVM可能會決定修剪結果以獲得更好的性能。
添加回答
舉報
