簡體   English   中英

JVM如何知道在運行時捕獲異常的位置?

[英]How does the JVM know where to catch an exception at runtime?

根據我的理解, throw是一個靈長類似的jvm命令。 調用它時,JVM“檢查當前調用堆棧是否可以捕獲它”。 如果它不能,那么java只是簡單地彈出調用棧,就好像調用了一個返回一樣。 然后jvm“檢查當前調用堆棧是否可以捕獲它”等等遞歸。

我的問題:JVM在算法上如何知道調用堆棧中哪些地方可以捕獲給定的異常? 每個調用堆棧條目中是否存儲了元數據,將異常映射到代碼塊? 堆中是否有一個靜態數據結構以某種方式跟蹤它? 因為某處必須有數據跟蹤。

JVM規范有關於此的詳細信息。

特別是, 第4.7.3節提供了有關異常表的詳細信息,該異常表是一系列條目,說明在哪些指令之間捕獲了異常。 第3.12節給出了一個具體的例子。

這個元數據如何映射到JIT的本機代碼當然是另一回事 - 而且是特定於實現的。 例如,可能存在從本機JITted代碼中的每個指令位置返回到原始字節碼位置的一些映射,此時可以查詢異常表以找到正確的處理程序。

一般來說:當拋出異常時,JVM會提取“調用堆棧”。 這標識了調用堆棧中每個級別正在執行的字節碼或機器指令,以及與該位置相關聯的類和方法。

然后,對於堆棧中的每個方法(從發生異常並向后工作的方法開始),JVM在方法的表中查找(在內部類對象中)將try / catch范圍映射到字節碼/機器指令范圍。

如果在方法的表中找到“匹配”,並且拋出的異常類型是在找到的范圍內監視的類,則在將異常設置為某種類型后,控制權將轉移到catch入口點。參數位置所以catch子句可以引用它。

如果在表中找不到“匹配”,則調用堆棧實際上是“彈出”,將下一個早期方法置於堆棧頂部,並在上面的方法的try / catch表中搜索“匹配”范圍重復。

這當然是一種過度簡化。 在處理finally范圍時涉及許多額外的邏輯,例如,和幾個“邊緣”情況。

暫無
暫無

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

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