2012-05-12 226 views
18

有人可以列出字節碼驗證器必須執行的主要任務來保證程序的正確性嗎?在JVM規範中是否定義了一組標準的,最小的職責?我還想知道驗證是否跨越其他階段,如加載和初始化。JVM字節碼驗證器的職責

回答

15

這是在JVM Specification: Chapter 4.10. Verification of class Files中指定的。

大部分頁面描述類型安全的各個方面。爲了檢查程序是否是類型安全的,驗證程序需要確定每個程序點的操作數棧中駐留的操作數類型,並確保它們與相應指令所期望的類型相匹配。

其他的事情它驗證包括,但不限於以下:

  • 分行必須是碼陣列的方法的範圍內。每個

  • 的所有控制流指令的目標是一個指令的開始。在寬指令的情況下,寬操作碼被認爲是指令的開始,並且由該寬指令修改操作的操作碼不被視爲開始指令。分支到指令的中間是不允許的。

  • 沒有指令可大於或等於局部變量的數目的指數下訪問或修改的局部變量,它的方法表示它分配。

  • 到常量池中的所有引用必須是相應類型的條目。 (例如,指令getfield命令必須引用的字段。)

  • 代碼不會在一個指令的中間結束。

  • 執行不能脫落的代碼的末尾。

  • 對於每個異常處理程序,由處理程序保護的代碼的起點和終點必須位於指令的開始位置,或者在終點處立即位於代碼的末尾。起點必須在結束點之前。異常處理程序代碼必須從有效的指令開始,並且不得從由寬指令修改的操作碼開始。

作爲最後的步驟,驗證還執行數據流分析,這使得確保沒有指令參考任何未初始化局部變量。

+0

從本地文件系統加載類時是否啓用了Java驗證程序?例如,當Eclipse或Apache加載一個類時,是否驗證了字節碼? –

7

另外,您也可以參考James Gosling的Java Language Environment白皮書。

enter image description here

字節碼校驗器遍歷的字節碼,構建 類型的狀態信息,並驗證參數類型的所有 字節碼指令。

圖顯示數據和控制的從Java語言 源代碼通過Java編譯器的流動,對類加載器和 字節碼校驗,因而對於Java虛擬機,其 包含解釋器和運行時系統。重要的問題是: Java類加載器和字節碼驗證器沒有做出關於字節碼流的主要來源的假設 可能來自本地系統,或者它可能已經在地球周圍中途行進了 。字節碼驗證程序充當一種關守: 它確保傳遞給Java解釋程序的代碼處於擬合狀態 以執行並且可以運行而不用擔心破壞Java解釋程序。直到它通過了驗證者的測試之後,導入的代碼才被允許以任何方式執行 。一旦驗證被 完成的,一些重要的特性是已知的:

  • 沒有操作數棧溢出或下溢
  • 該類型的所有字節碼指令的參數是已知的永遠是正確的
  • 對象字段的訪問被稱爲是合法的 - 私人的,公共的,或者保護

雖然這一切似乎檢查詳細奇慢,由時間 字節碼校驗完成工作,爲Java int erpreter可以在 的情況下繼續,因爲知道代碼將安全運行。瞭解這些 屬性使Java解釋器更快,因爲它不需要檢查任何東西。沒有操作數類型檢查,也沒有堆棧溢出檢查。口譯員因此可以在不影響可靠性的情況下以全速運行 。