日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

JVM核心之JVM运行和类加载全过程

發(fā)布時(shí)間:2023/12/10 编程问答 68 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JVM核心之JVM运行和类加载全过程 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

為什么研究類(lèi)加載全過(guò)程?

  • 有助于連接JVM運(yùn)行過(guò)程
  • 更深入了解java動(dòng)態(tài)性(解熱部署,動(dòng)態(tài)加載),提高程序的靈活性

?

類(lèi)加載機(jī)制

  • JVM把class文件加載到內(nèi)存,并對(duì)數(shù)據(jù)進(jìn)行校驗(yàn)、解析和初始化,最終形成JVM可以直接使用的java類(lèi)型的全過(guò)程。

?

?

?

  • 加載
    • 將class文件字節(jié)碼內(nèi)容加載到內(nèi)存中,并將這些靜態(tài)數(shù)據(jù)轉(zhuǎn)換成方法區(qū)中的運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu),在堆中生成一個(gè)代表這個(gè)類(lèi)的java.lang.Class對(duì)象,作為方法區(qū)類(lèi)數(shù)據(jù)的訪問(wèn)入口,這個(gè)過(guò)程需要類(lèi)加載器參與。

?

?

?

  • 鏈接??? 將java類(lèi)的二進(jìn)制代碼合并到JVM的運(yùn)行狀態(tài)之中的過(guò)程
    •   驗(yàn)證:確保加載的類(lèi)信息符合JVM規(guī)范,沒(méi)有安全方面的問(wèn)題
    •   準(zhǔn)備:正式為類(lèi)變量(static變量)分配內(nèi)存并設(shè)置類(lèi)變量初始值的階段,這些內(nèi)存都將在方法去中進(jìn)行分配
    •   解析:虛擬機(jī)常量池的符號(hào)引用替換為字節(jié)引用過(guò)程
  • 初始化
    • 初始化階段是執(zhí)行類(lèi)構(gòu)造器<clinit>()方法的過(guò)程。類(lèi)構(gòu)造器<clinit>()方法是由編譯器自動(dòng)收藏類(lèi)中的所有類(lèi)變量的賦值動(dòng)作和靜態(tài)語(yǔ)句塊(static塊)中的語(yǔ)句合并產(chǎn)生
    • 當(dāng)初始化一個(gè)類(lèi)的時(shí)候,如果發(fā)現(xiàn)其父類(lèi)還沒(méi)有進(jìn)行過(guò)初始化,則需要先觸發(fā)其父類(lèi)的初始化
    • 虛擬機(jī)會(huì)保證一個(gè)類(lèi)的<clinit>()方法在多線程環(huán)境中被正確加鎖和同步
    • 當(dāng)范圍一個(gè)Java類(lèi)的靜態(tài)域時(shí),只有真正聲名這個(gè)域的類(lèi)才會(huì)被初始化

?

?

例1:

?

public class Demo01 {public static void main(String[] args) {A a = new A();System.out.println(a.width);} }class A{public static int width=100; //靜態(tài)變量,靜態(tài)域 fieldstatic{System.out.println("靜態(tài)初始化類(lèi)A");width = 300 ;}public A() {System.out.println("創(chuàng)建A類(lèi)的對(duì)象");} }

?

?

分析:

說(shuō)明:

內(nèi)存中存在棧、堆(放創(chuàng)建好的對(duì)象)、方法區(qū)(實(shí)際也是一種特殊堆)

1、JVM加載Demo01時(shí)候,首先在方法區(qū)中形成Demo01類(lèi)對(duì)應(yīng)靜態(tài)數(shù)據(jù)(類(lèi)變量、類(lèi)方法、代碼…),同時(shí)在堆里面也會(huì)形成java.lang.Class對(duì)象(反射對(duì)象),代表Demo01類(lèi),通過(guò)對(duì)象可以訪問(wèn)到類(lèi)二進(jìn)制結(jié)構(gòu)。然后加載變量A類(lèi)信息,同時(shí)也會(huì)在堆里面形成a對(duì)象,代表A類(lèi)。

2、main方法執(zhí)行時(shí)會(huì)在棧里面形成main方法棧幀,一個(gè)方法對(duì)應(yīng)一個(gè)棧幀。如果main方法調(diào)用了別的方法,會(huì)在棧里面挨個(gè)往里壓,main方法里面有個(gè)局部變量A類(lèi)型的a,一開(kāi)始a值為null,通過(guò)new調(diào)用類(lèi)A的構(gòu)造器,棧里面生成A()方法同時(shí)堆里面生成A對(duì)象,然后把A對(duì)象地址付給棧中的a,此時(shí)a擁有A對(duì)象地址。

3、當(dāng)調(diào)用A.width時(shí),調(diào)用方法區(qū)數(shù)據(jù)。

?

當(dāng)類(lèi)被引用的加載,類(lèi)只會(huì)加載一次

  • 類(lèi)的主動(dòng)引用(一定會(huì)發(fā)生類(lèi)的初始化)
    • new一個(gè)類(lèi)的對(duì)象
    • 調(diào)用類(lèi)的靜態(tài)成員(除了final常量)和靜態(tài)方法
    • 使用java.lang.reflect包的方法對(duì)類(lèi)進(jìn)行反射調(diào)用
    • 當(dāng)虛擬機(jī)啟動(dòng),java Demo01,則一定會(huì)初始化Demo01類(lèi),說(shuō)白了就是先啟動(dòng)main方法所在的類(lèi)
    • 當(dāng)初始化一個(gè)類(lèi),如果其父類(lèi)沒(méi)有被初始化,則先初始化它父類(lèi)
  • 類(lèi)的被動(dòng)引用(不會(huì)發(fā)生類(lèi)的初始化)
    • 當(dāng)訪問(wèn)一個(gè)靜態(tài)域時(shí),只有真正聲名這個(gè)域的類(lèi)才會(huì)被初始化
      • 通過(guò)子類(lèi)引用父類(lèi)的靜態(tài)變量,不會(huì)導(dǎo)致子類(lèi)初始化
    • 通過(guò)數(shù)組定義類(lèi)的引用,不會(huì)觸發(fā)此類(lèi)初始化
    • 引用常量不會(huì)觸發(fā)此類(lèi)的初始化(常量在編譯階段就存入調(diào)用類(lèi)的常量池中了)

例2:

?

public class Demo01 {static{System.out.println("靜態(tài)初始化Demo01");}public static void main(String[] args) throws Exception {System.out.println("Demo01的main方法!");System.out.println(System.getProperty("java.class.path"));//主動(dòng)引用 // new A(); // System.out.println(A.width); // Class.forName("com.sinosoft.test.A");//被動(dòng)引用 // System.out.println(A.MAX); // A[] as = new A[10];System.out.println(B.width);//B類(lèi)不會(huì)被加載} }class B extends A {static {System.out.println("靜態(tài)初始化B");} }class A extends A_Father {public static int width=100; //靜態(tài)變量,靜態(tài)域 fieldpublic static final int MAX=100; static {System.out.println("靜態(tài)初始化類(lèi)A");width=300;}public A(){System.out.println("創(chuàng)建A類(lèi)的對(duì)象");} }class A_Father extends Object {static {System.out.println("靜態(tài)初始化A_Father");} }

?

?

總結(jié)

以上是生活随笔為你收集整理的JVM核心之JVM运行和类加载全过程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。