溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

JVM中類的初始化及新建過程是怎樣的

發(fā)布時間:2021-10-23 16:00:24 來源:億速云 閱讀:107 作者:柒染 欄目:大數(shù)據(jù)

JVM中類的初始化及新建過程是怎樣的,針對這個問題,這篇文章詳細介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

類的狀態(tài)變化

類的初始化主要經(jīng)歷加載->鏈接(驗證,準備,解析)->初始化這些階段,與JVM中相對應(yīng)的狀態(tài)如下圖所示

instanceKlass.hpp

JVM中類的初始化及新建過程是怎樣的

allocated: 已分配,但尚未鏈接

loaded: 已加載,并插入到JVM內(nèi)部類層次體系中,但尚未鏈接

linked: 已鏈接,但尚未初始化

being_initialized: 初始化中

fully_initialized: 完成初始化

initialization_error: 初始化過程中出錯

加載

.class文件是個二進制文件,我們可以點開.class文件,可以看到各種二進制信息, 右邊轉(zhuǎn)成的字符不是很全, 有很多標識位,直接用數(shù)字表示的. 右邊能看到的, 基本上都是常量池字符串里面的信息

JVM中類的初始化及新建過程是怎樣的

加載.class的源碼在classFileParser.cpp 中,如下圖所示:

JVM中類的初始化及新建過程是怎樣的

在上圖中, 我們可以看到, 有CAFEBABE的定義,版本號的定義, 在往下, 我們可以看到對class文件中的常量池,附錄表等解析方法,在此就不在贅述

鏈接

如我們在out/build 或者別的輸出目錄中所看到的, class文件都是單獨的, class文件中有本類用到的各種靜態(tài)常量池. 在jvm中還有一個運行時常量池,是各個class都可以訪問的. 因為鏈接最主要的就是把class文件中的靜態(tài)常量池和運行時常量池關(guān)聯(lián)起來, 把靜態(tài)符號引用,轉(zhuǎn)成直接內(nèi)存引用, 然后我們就可以通過地址調(diào)用相應(yīng)的方法,完成操作

鏈接有三大步,驗證, 準備,解析.

驗證: 類或接口的二進制信息是否正確, 方法的訪問控制, 變量是否初始化等. 通常來說, 只要我們寫代碼時ide不報錯, 基本上就沒什么問題, 但有些會自己構(gòu)造.class文件,交由jvm運行, 所以要驗證各種正確性

準備: 在類的準備階段,將為類靜態(tài)變量分配內(nèi)存空間,和賦初始值,但是要注意, 這時候還沒有執(zhí)行任何賦值的代碼或者靜態(tài)代碼塊!

解析: 如上所述, 把class文件中的靜態(tài)變量池和jvm內(nèi)部的運行池給關(guān)聯(lián)起來, 把符號引用換成直接引用

源碼位置如下圖所示:

JVM中類的初始化及新建過程是怎樣的

clinit 方法

clinit方法是初始化的關(guān)鍵所在

這個方法, 我們在java源代碼中沒有看到過,該方法只能由javac 編譯器自動生成和命名,然后自動插入到Class文件中.

clinit方法由編譯器收集類變量(靜態(tài)非final),static 代碼塊

clinit方法沒有任何虛擬機字節(jié)碼指令可以調(diào)用, 它只能在類型初始化階段被虛擬機隱式調(diào)用,全程只調(diào)用一次

如果有繼承的話,會先初始化父類

其源碼如下:

JVM中類的初始化及新建過程是怎樣的

如上圖所示,有多個步驟,每個步驟的注釋也十分清晰, 強烈建議小伙伴們把源碼拉下來閱讀一下

其實父類優(yōu)先于子類初始化,可以步驟7和步驟8中看到,如下圖所示:

JVM中類的初始化及新建過程是怎樣的

實例對象的創(chuàng)建

實例對象的創(chuàng)建, 這一塊相對來說就簡單了, 虛擬機遇到new的時候, 從棧頂取得目標對象在常量池中的索引,接著定位到目標類型的類型,接下來,虛擬機看是否已加載采用tlabs/慢速分配(Eden)找一塊空地, 然后完成實例數(shù)據(jù)和對象頭的初始化.

流程就是上面?zhèn)€流程,其實也沒啥復(fù)雜的, 就像我們買東西, 在京東上看了圖片(klass) ,然后就買了一個回來(有自己的實例), 如果快遞配送的很快,還沒來得及想好放哪(還沒加載這個類),那就先丟到倉庫(Eden區(qū)),已經(jīng)想好怎么放的話(已加載了這個類),那就順手就給安排了(使用TLABS來分配).

其中要注意的一點就是.一但選好放哪里之后, 就開始在自己的小本本上更新,XXX東西被我放在了XXX地址. 即使現(xiàn)在還沒有走過去把東西放下, 別人問的時候,已經(jīng)可以用那個地址去回答別人了.

源碼入口如下圖所示,有興趣的小伙伴,可以沿著這個入口,深入跟蹤下去, 小刀后面也會和大家一起再次看這些地方的! 加油

JVM中類的初始化及新建過程是怎樣的

關(guān)于JVM中類的初始化及新建過程是怎樣的問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識。

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

jvm
AI