jvm 一行代碼是怎么運行的:
首先豁延,java代碼會被編譯成字節(jié)碼尚困,字節(jié)碼就是java虛擬機定義的一種編碼格式昧旨,需要java虛擬機才能夠解析查乒,java虛擬機需要將字節(jié)碼轉(zhuǎn)換成機器碼才能在cpu上執(zhí)行。
jvm如何加載一個類:
第一步:加載盒发,雙親委派:啟動類加載器(jre/lib)例嘱,系統(tǒng)擴展類加載器(ext/lib),應(yīng)用類加載器(classpath)宁舰,前者為c++編寫拼卵,所以系統(tǒng)加載器的parent為空,后面兩個類加載器都是通過啟動類加載器加載完成后才能使用蛮艰。加載的過程就是查找字節(jié)流腋腮,可以通過網(wǎng)絡(luò),也可以自己在代碼生成壤蚜,也可以來源一個jar包即寡。另外,同一個類仍律,被不同的類加載器加載嘿悬,那么他們將不是同一個類实柠,java中通過類加載器和類的名稱來界定唯一水泉,所以我們可以在一個應(yīng)用成存在多個同名的類的不同實現(xiàn)。
第二步:鏈接:(驗證窒盐,準備草则,解析) 驗證主要是校驗字節(jié)碼是否符合約束條件,一般在字節(jié)碼注入的時候關(guān)注的比較多蟹漓。準備:給靜態(tài)字段分配內(nèi)存炕横,但是不會初始化,解析主要是為了將符號引用轉(zhuǎn)換為實際引用葡粒,可能會觸發(fā)方法中引用的類的加載份殿。
第三步:初始化膜钓,如果賦值的靜態(tài)變量是基礎(chǔ)類型或者字符串并且是final的話,該字段將被標(biāo)記為常量池字段卿嘲,另外靜態(tài)變量的賦值和靜態(tài)代碼塊颂斜,將被放在一個叫cinit的方法內(nèi)被執(zhí)行,為了保證cinit方法只會被執(zhí)行一次拾枣,這個方法會加鎖沃疮,我們一般實現(xiàn)單例模式的時候為保證線程安全,會利用類的初始化上的鎖梅肤。 初始化只有在特定條件下才會被觸發(fā)司蔬,例如new 一個對象,反射被調(diào)用姨蝴,靜態(tài)方法被調(diào)用等俊啼。