我看Java虛擬機(5)---虛擬機加載機制

經過上節的講解,我們已經知道了Java代碼——》字節碼的過程,產生了字節碼,下一步就是將字節碼讀入虛擬機,虛擬機將該部分分爲七個步驟:
加載->驗證->準備->解析->初始化->使用->卸載
我們主要研究前5步。

加載

  • 讀入二進制字節流,並不限定是class文件,可以是zip,jar,網絡獲取或者其他。
  • 將字節流代表的靜態結構轉換爲方法區的運行時數據結構
  • 在堆中創建代表這個類的java.lang.class對象,作爲方法區這些數據的訪問入口

驗證

  • 文件格式驗證,由於虛擬機只規定了讀入的是二進制字節流,並未規定必須是class文件,所以有可能是惡意的二進制流,爲了防止其破壞虛擬機,所以對其文件格式進行驗證:魔數是否0xCAFEBABE開頭,主次版本等。
  • 元數據驗證,對類的元數據信息進行語義進行校驗,保證不存在不符合Java規範的元數據。是否有父類,是否爲抽象類,是否實現了接口或父類要求實現的方法等
  • 字節碼驗證,最複雜的一步,數據流和控制流分析。
  • 符號引用驗證,解析階段發生,將符號引用轉換爲直接引用。

準備

爲類變量賦初始值,但並不是爲其賦真正的值,比如:

public static int a = 1;

該步爲a在方法區分配空間,並賦值爲0,特殊的final:

public static final int a = 1;

則該步將直接給a賦值爲1

解析:

符號引用:以一組符號來定位所引用的目標。
直接引用:直接指向目標的指針,相對偏移量或者能間接定位到目標的句柄。
針對類或接口,字段,方法,接口方法四類符號進行解析,將符號引用轉換爲直接引用。

初始化:

以下四種方式會觸發類的初始化:

  • 使用new,引用類static變量,static方法,除了final修飾的字段和方法。
  • 使用reflect進行反射調用
  • 父類
  • main方法所在的類,啓動類

書中還介紹了類加載器相關內容,其中實例練習也是關於此部分的,就在這記錄下,我學習到的東西吧!
雙親委派模型,即類優先讓其父類加載,一般是以組合關係來複用父類加載器。(我就不上圖了,網上一大把)。Java有三種類加載器:啓動類加載器,擴展類加載器,應用程序類加載器,自定義的類加載器需要繼承應用程序類加載器。
值得一提的是,虛擬機識別類,是根據其加載器類本身識別的。同一個類,有不同類加載器加載後,他們是不相等的。
雙親委派模型例子:Tomcat,common類庫(其加載器繼承應用程序類加載器),tomcat和所有應用程序公用;server類庫,只能被tomcat使用;shared類庫只能被所有應用程序使用,禁止tomcat使用;WEB-INF類庫被特定的應用程序使用。
雙親委派模型的破壞:OSGI,具有熱插拔特性,並非按照雙親委派模型。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章