Python知識分享網(wǎng) - 專業(yè)的Python學習網(wǎng)站 學Python,上Python222
《劍指offer》JVM面試題總結(jié)
發(fā)布于:2024-01-18 11:15:36
(假如點擊沒反應(yīng),多刷新兩次就OK!)

《劍指offer》JVM面試題總結(jié)   圖1

 

 

 

 

資料內(nèi)容:


加載
關(guān)于什么時候開始加載這個過程,《Java 虛擬機規(guī)范》并沒有強制約束,所以這一點我們可以
自由實現(xiàn)。加載是整個類加載過程的第一個階段,在這個階段,Java 虛擬機需要完成三件事
情:
• 通過一個類的全限定名來獲取定義此類的二進制字節(jié)流。
• 將這個字節(jié)流表示的一種存儲結(jié)構(gòu)轉(zhuǎn)換為運行時數(shù)據(jù)區(qū)中方法區(qū)的數(shù)據(jù)結(jié)構(gòu)。
• 在內(nèi)存中生成一個 Class 對象,這個對象就代表了這個數(shù)據(jù)結(jié)構(gòu)的訪問入口。
《Java 虛擬機規(guī)范》并未規(guī)定全限定名是如何獲取的,所以現(xiàn)在業(yè)界有很多獲取全限定名的方
式:
• 從 ZIP 包中讀取,最終會改變?yōu)?JAR、EAR、WAR 格式。
• 從網(wǎng)絡(luò)中獲取,最常見的應(yīng)用就是 Web Applet。
• 運行時動態(tài)生成,使用最多的就是動態(tài)代理技術(shù)。
• 由其他文件生成,比如 JSP 應(yīng)用場景,由 JSP 文件生成對應(yīng)的 Class 文件。
• 從數(shù)據(jù)庫中讀取,這種場景就比較小了。
• 可以從加密文件中獲取,這是典型的防止 Class 文件被反編譯的保護措施。
加載階段既可以使用虛擬機內(nèi)置的引導類加載器來完成,也可以使用用戶自定義的類加載器來完
成。程序員可以通過自己定義類加載器來控制字節(jié)流的訪問方式。
數(shù)組的加載不需要通過類加載器來創(chuàng)建,它是直接在內(nèi)存中分配,但是數(shù)組的元素類型(數(shù)組去
掉所有維度的類型)最終還是要靠類加載器來完成加載。
驗證
加載過后的下一個階段就是驗證,因為我們上一步講到在內(nèi)存中生成了一個 Class 對象,這個
對象是訪問其代表數(shù)據(jù)結(jié)構(gòu)的入口,所以這一步驗證的工作就是確保 Class 文件的字節(jié)流中的
內(nèi)容符合《Java 虛擬機規(guī)范》中的要求,保證這些信息被當作代碼運行后,它不會威脅到虛擬
機的安全。
驗證階段主要分為四個階段的檢驗:
• 文件格式驗證。
• 元數(shù)據(jù)驗證。
• 字節(jié)碼驗證。
• 符號引用驗證。
文件格式
文件格式驗證
這一階段可能會包含下面這些驗證點:
• 魔數(shù)是否以 0xCAFEBABE 開頭。
• 主、次版本號是否在當前 Java 虛擬機接受范圍之內(nèi)。
• 常亮池的常量中是否有不支持的常量類型。
• 指向常量的各種索引值中是否有指向不存在的常量或不符合類型的常量。
• CONSTANT_Utf8_info 型的常量中是否有不符合 UTF8 編碼的數(shù)據(jù)。
• Class 文件中各個部分及文件本身是否有被刪除的或附加的其他信息。
實際上驗證點遠遠不止有這些,上面這些只是從 HotSpot 源碼中摘抄的一小段內(nèi)容。
元數(shù)據(jù)
元數(shù)據(jù)驗證
這一階段主要是對字節(jié)碼描述的信息進行語義分析,以確保描述的信息符合《Java 語言規(guī)
范》,驗證點包括
• 驗證的類是否有父類(除了 Object 類之外,所有的類都應(yīng)該有父類)。
• 要驗證類的父類是否繼承了不允許繼承的類。
• 如果這個類不是抽象類,那么這個類是否實現(xiàn)了父類或者接口中要求的所有方法。
• 是否覆蓋了 final 字段,是否出現(xiàn)了不符合規(guī)定的重載等。
需要記住這一階段只是對《Java 語言規(guī)范》的驗證。

字節(jié)碼驗證
字節(jié)碼驗證階段是最復雜的一個階段,這個階段主要是確定程序語意是否合法、是否是符合邏輯
的。這個階段主要是對類的方法體(Class 文件中的 Code 屬性)進行校驗分析。這部分驗證包

• 確保操作數(shù)棧的數(shù)據(jù)類型和實際執(zhí)行時的數(shù)據(jù)類型是否一致。
• 保證任何跳轉(zhuǎn)指令不會跳出到方法體外的字節(jié)碼指令上。
• 保證方法體中的類型轉(zhuǎn)換是有效的,例如可以把一個子類對象賦值給父類數(shù)據(jù)類
型,但是不能把父類數(shù)據(jù)類型賦值給子類等諸如此不安全的類型轉(zhuǎn)換。
• 其他驗證。
如果沒有通過字節(jié)碼驗證,就說明驗證出問題。但是不一定通過了字節(jié)碼驗證,就能保證程序是
安全的。