簡體   English   中英

java字節碼優化,如何處理異常

[英]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 甚至可能永遠不會創建包含變量xC實例,因為不需要產生打印該消息的副作用。 這是所有您不會注意到的變化…

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM