[英]java bytecode optimization, how to handle exception
考慮以下沒有並發訪問的Java類。
class C{
int x;
public void m1(int y){
this.x = y;
m2(y);
}
public void m2(int y){
System.out.println("m2"); <- or anything else that does not affect this.x
}
}
+ edit由於m1()僅對y具有讀-讀關系,因此jit編譯器能否通過將執行順序更改為以下內容來優化m1()? 它破壞了Java模型的一致性嗎? -編輯
public void m1(int y){
m2(y);
this.x = y;
}
如果可以優化m1(),如果m2()在優化的代碼中引發異常,該影響仍會執行嗎?
我不了解javase7規范,在這種情況下會發生什么?
oracle.com/javase/specs/jvms/se7
Java虛擬機可以允許在引發異步異常之前執行少量但有限的執行。 允許使用此延遲,以使優化的代碼可以在遵循Java編程語言的語義的情況下在實際可行的位置檢測並拋出這些異常。
[...] Java虛擬機引發的異常是精確的:當發生控制轉移時, 必須在發生異常的那一點之前執行的所有指令效果已經發生 。 引發異常后的任何指令似乎都沒有被評估。 如果優化的代碼已經推測性地執行了發生異常之后的某些指令,則必須准備此類代碼以使該推測性執行對程序的用戶可見狀態隱藏
我了解回滾行為,但不了解“未執行”指令會發生什么。 從技術上講,這種影響不是由於優化而“執行”的,這是否意味着它永遠不會執行?
您將兩個概念放在一起,它們的唯一共同點是您不理解它們。
重新排序是一種優化,絕不允許修改代碼執行的結果。 因此,過時地提出這樣的問題:“ 是否允許JVM以破壞代碼的方式對代碼重新排序? ”。 當然不是。 唯一可能的是,在沒有適當同步的情況下,結果可能會以不同的順序出現在不同的線程上。
此外,你應該問自己為什么
public void m1(int y){
m2(y);
this.x = y;
}
是對
public void m1(int y){
this.x = y;
m2(y);
}
有什么改進?
您從規范中選擇的另一件事是異步異常 ,這是一種僅適用於兩種情況的特殊情況 :
–調用了Thread或ThreadGroup類的stop方法,或者
– Java虛擬機實現中發生內部錯誤
這些顯然是非常特殊的條件,並且很明顯,不需要為不斷輪詢這些條件而需要優化的代碼。 引用的段落描述了可以延遲此類異常的情況,但是應該清楚這些限制不會解除其他現有限制,即優化可能不會更改執行結果。
換句話說,查看孤立的指令並認為JVM沒有什么比將它們改組更好的了。 優化的一般規則是,它們不得更改可觀察的效果,並且我們無法從該單獨的代碼段中分辨出應用程序中可觀察的內容。 例如,如果永不讀取變量x
,則可能根本就不會寫入變量x
。 甚至可能永遠不會創建包含變量x
的C
實例,因為不需要產生打印該消息的副作用。 這是所有您不會注意到的變化…
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.