JVM加載類的時機與過程

類的加載過程概況

類從被加載到虛擬機內存開始,直到卸載出內存已慢,它的生命周期包含了:加載曲聂,驗證,準備佑惠,解析朋腋,初始化,使用和卸載7個階段膜楷。



其中旭咽,加載,驗證赌厅,準備穷绵,初始化和卸載五個階段是順序是固定的。這些階段通常都是相互交叉混合進行的特愿,不過順序不會亂仲墨。解析階段在某些情況下可以在初始化之后再開始,這是為了Java語言的運行時綁定揍障。

引發(fā)類的初始化的條件

類的初始化階段往往是真正執(zhí)行類中定義的java程序代碼的過程目养。按照程序員主觀定義去初始化類變量和其他資源。
類加載的第一個階段“”“加載”毒嫡,虛擬機本沒有強制規(guī)定混稽,但是對于初始化進行了嚴格的規(guī)定 。有且僅有以下五種情況下必須對類進行初始化:

  • 使用new關鍵字實例化一個對象审胚,或者訪問(讀取和設置)類的靜態(tài)變量(被final修飾的除外匈勋,常量是一種特殊的變量,編譯器將其當做值而非域來對待膳叨,這是一種優(yōu)化)洽洁,以及調用一個類的靜態(tài)方法的時候。
  • 使用java.lang.reflect包中的方法對類進行反射調用的時候菲嘴。
    以下是獲取類的三種方式饿自。
  1. 通過類名.class方式Class<?> cType = ClassName.class
  2. 通過Class.forName()方法獲得,Class<?> cType = Class.forName("類全名")
  3. 通過對象名.getClass()方法獲取龄坪,Class<?> cType = objName.getClass();
    區(qū)別:第一種方式不執(zhí)行靜態(tài)塊和動態(tài)構造塊昭雌。第二種方式是執(zhí)行靜態(tài)塊不執(zhí)行動態(tài)構造塊。第三種方式執(zhí)行靜態(tài)塊和動態(tài)構造塊健田。
    以下是獲取類之后利用反射創(chuàng)建對象的方式:
  4. 通過Class對象的newInstance的方法烛卧,局限為只能調用默認的構造函數(shù)
  5. 通過取得Class對象的getConstructor方法取得Constructor對象,然后通過調用Constructor類的newInstance的兩個方法妓局。
  6. 通過Array.newInstance方法來創(chuàng)建對象,不過只適用于數(shù)組总放。
  • 當初始化一個類的時候呈宇,如果發(fā)現(xiàn)其父類還沒有進行初始化,則需要觸發(fā)其父類的初始化局雄。
  • 當虛擬機啟動的時候甥啄,用戶需要指定一個需要執(zhí)行的main類,虛擬機會先初始化這個主類炬搭。
    以上情況稱為對一個類的主動引用蜈漓,被動引用不會引發(fā)類的初始化。
    注意:接口的加載過程和類的加載過程稍有不同宫盔,接口中不能使用static{}塊迎变,當一個接口在初始化時,并不要求其父接口全部完成初始化飘言,只有真正使用帶父接口的時候(引用接口中定義的常量)才會初始化
    被動引用 :1衣形、 子類調用父類的靜態(tài)變量,子類不會被初始化姿鸿,只有父類被初始化谆吴,對于靜態(tài)字段,只有直接定義此變量的類才可以被初始化苛预。
    2句狼、通過數(shù)組定義來引用類,不會觸發(fā)類的初始化热某。
    3腻菇、訪問類的常量,不會初始化類昔馋。

類加載過程

加載階段

預加載:虛擬機啟動自動加載JAVA_HOME/lib/rt.jar中的基礎類筹吐,可以通過-XX:+TraceClassLoading來查看輸出。
運行時加載:虛擬機用到.class文件的時候秘遏,會去內存中查看一下.class是否存在丘薛,如果沒有就按照類的全限定名來加載此類。
加載階段主要做了以下三件事情:
1邦危、獲取.class文件的二進制流
2洋侨、將字節(jié)流中的類信息、靜態(tài)變量倦蚪、字節(jié)碼希坚、常量這些.class文件中的內容放入方法區(qū)中。
3陵且、在內存中生成一個代表這個對象的java.lang.Class對象裁僧。作為此類所有數(shù)據(jù)的入口。

驗證階段

這一階段的目的是為了確保Class文件的字節(jié)流中包含的信息符合當前虛擬機的要求。

準備階段

準備階段是正式為類變量分配內存并設置其初始值的時候锅知,內存都是被分配到方法區(qū)中播急。準備階段不分配類中的實例變量的內存脓钾,實例變量的內存將會在對象實例化的時候隨著對象一起分配到java堆中售睹。
public static int value=123;在準備階段value的初始值為0,在初始化階段才會變?yōu)?23可训;

解析階段

解析階段是將符號引用轉化為直接引用的過程昌妹。
符號引用是用一組符號來表示所引用的類和接口的全限定名、字段的名字和類型握截、方法的名字和類型飞崖,只要使用時可以無歧義的定位即可。符號引用與虛擬機實現(xiàn)的內存布局無關谨胞,引用的目標并不一定已經(jīng)加載到內存中固歪。
直接引用是直接指向目標的指針、相對偏移量和一個能間接定位到目標的句柄胯努。直接引用與虛擬機的內存布局是相關的牢裳,有了直接引用,說明引用的目標已經(jīng)在內存中叶沛。

初始化階段

類初始化時類加載過程的最后一步蒲讯,前面的類加載過程,除了在加載階段用戶可以通過自定義類加載器參與之外灰署,其余動作完全由虛擬機主導和控制判帮。到了初始化階段,才真正執(zhí)行類中定義的java代碼溉箕。
其實初始化階段做的是就是給static變量賦予用戶指定的值和靜態(tài)執(zhí)行代碼塊晦墙。
初始化階段是執(zhí)行類構造器<clinit>()方法的過程。<clinit>()方法是由編譯器自動收集類中的類變量的賦值動作和靜態(tài)語句塊中的語句合并產(chǎn)生肴茄。
虛擬機會保證類的初始化在多線程環(huán)境中被正確地加鎖偎痛、同步,即如果多個線程同時去初始化一個類独郎,那么只會有一個類去執(zhí)行這個類的<clinit>()方法踩麦,其他線程都要阻塞等待,直至活動線程執(zhí)行<clinit>()方法完畢氓癌。因此如果在一個類的<clinit>()方法中有耗時很長的操作谓谦,就可能造成多個進程阻塞。不過其他線程雖然會阻塞贪婉,但是執(zhí)行<clinit>()方法的那條線程退出<clinit>()方法后反粥,其他線程不會再次進入<clinit>()方法了,因為同一個類加載器下,一個類只會初始化一次才顿。也就是說初始化之前的階段可以有多個線程執(zhí)行莫湘,而初始化階段只能有一個線程執(zhí)行

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市郑气,隨后出現(xiàn)的幾起案子幅垮,更是在濱河造成了極大的恐慌,老刑警劉巖尾组,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件忙芒,死亡現(xiàn)場離奇詭異,居然都是意外死亡讳侨,警方通過查閱死者的電腦和手機呵萨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來跨跨,“玉大人潮峦,你說我怎么就攤上這事∮掠ぃ” “怎么了忱嘹?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長咆耿。 經(jīng)常有香客問我德谅,道長,這世上最難降的妖魔是什么萨螺? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任窄做,我火速辦了婚禮,結果婚禮上慰技,老公的妹妹穿的比我還像新娘椭盏。我一直安慰自己,他們只是感情好吻商,可當我...
    茶點故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布掏颊。 她就那樣靜靜地躺著,像睡著了一般艾帐。 火紅的嫁衣襯著肌膚如雪乌叶。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天柒爸,我揣著相機與錄音准浴,去河邊找鬼。 笑死捎稚,一個胖子當著我的面吹牛乐横,可吹牛的內容都是我干的求橄。 我是一名探鬼主播,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼葡公,長吁一口氣:“原來是場噩夢啊……” “哼罐农!你這毒婦竟也來了?” 一聲冷哼從身側響起催什,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤涵亏,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蛆楞,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體溯乒,經(jīng)...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡夹厌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年豹爹,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片矛纹。...
    茶點故事閱讀 38,625評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡臂聋,死狀恐怖,靈堂內的尸體忽然破棺而出或南,到底是詐尸還是另有隱情孩等,我是刑警寧澤,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布采够,位于F島的核電站肄方,受9級特大地震影響,放射性物質發(fā)生泄漏蹬癌。R本人自食惡果不足惜权她,卻給世界環(huán)境...
    茶點故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望逝薪。 院中可真熱鬧隅要,春花似錦、人聲如沸董济。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽虏肾。三九已至廓啊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間封豪,已是汗流浹背谴轮。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留撑毛,地道東北人书聚。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓唧领,卻偏偏與公主長得像,于是被迫代替她去往敵國和親雌续。 傳聞我的和親對象是個殘疾皇子斩个,可洞房花燭夜當晚...
    茶點故事閱讀 43,492評論 2 348

推薦閱讀更多精彩內容