Java加載類(Class)文件過程

其實對於任何編程語言而言,編譯和鏈接都是必不可少的環節,對於java而言編譯這環節比較簡單,就是按照JVM指定的規範生成字節碼文件(Class文件),因爲字節碼是JVM能認識的,並且會把這些字節碼翻譯成本地機器的機器指令。至於鏈接這塊,Java作爲動態動態編譯編程語言,鏈接這塊相對靜態鏈接語言而言要複雜很多。某種程度可以說java的Class文件加載處理的過程其實就是爲了完成鏈接這個目標。鏈接這個詞比較抽象,說白一句話:鏈接就是想方設法去確定每個對象,每個成員,每個方法在內存中的全局地址。不管是C++還是java都是這個目標。對於C++而言,是通過符號表和每個文件的局部偏移量這兩個信息來實現這個目標,而java作爲動態編譯語言而言,就沒那麼簡單直觀了。(其實說java是動態編譯語言不如說java是動態鏈接語言

1.  加載

通過類加載器加載編譯好的Class文件,主要工作就是把Class文件中的常量池段放置到JVM方法區的常量池中,把Class文件中的方法代碼放置到JVM的方法區中,最終產品是在JVM的堆區中創建了一個Class對象,該對象保存了類相關的一些信息,比如類名等(目前還不知道是否保存了完整的Class文件字節碼),並且保存了一份指向方法區中類各種相關數據的指針,作爲入口。至於類加載器的子類,雙親委託模型等概念還需進一步瞭解。

2.  鏈接

鏈接的過程分成3小步:

(1)    驗證

驗證說白了就是驗證加載進來的Class文件裏面的數據內容是否符合JVM指定的規範,包括格式驗證,語義驗證,操作驗證,如果不滿足規範,JVM後續將無法正常使用該類。

(2)    準備

主要就是對靜態數據進行分配內存和設定初始值(這個初始值不是代碼中指定的初始值,而是JVM按照它的意願設置的)

(3)    解析

這步是重中之重,主要工作是把方法區中加載進來的常量池中的符號引用通過解析過程替換成直接引用(內存地址),類似C++的符號表在鏈接時幫助每個成員和方法確定全局偏移量。這也是整個JAVA在加載類文件後完成鏈接目標的核心最關鍵一步。具體解析過程後續再補上。

3. 初始化

         這個環節相對簡單,就是根據代碼的初始化內容對類中的靜態數據進行賦值操作。

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