好程序員Java學(xué)習(xí)路線分享JVM類加載機(jī)制-創(chuàng)新互聯(lián)

好程序員Java學(xué)習(xí)路線分享JVM類加載機(jī)制,JVM相關(guān)概念

成都創(chuàng)新互聯(lián)為企業(yè)級客戶提高一站式互聯(lián)網(wǎng)+設(shè)計服務(wù),主要包括成都網(wǎng)站建設(shè)、成都網(wǎng)站制作、重慶APP軟件開發(fā)、重慶小程序開發(fā)公司、宣傳片制作、LOGO設(shè)計等,幫助客戶快速提升營銷能力和企業(yè)形象,創(chuàng)新互聯(lián)各部門都有經(jīng)驗豐富的經(jīng)驗,可以確保每一個作品的質(zhì)量和創(chuàng)作周期,同時每年都有很多新員工加入,為我們帶來大量新的創(chuàng)意。 
  • jdk<br>
    jdk(Java Development Kit)Java開發(fā)包,是Java開發(fā)人員用于編譯和調(diào)試程序的一套程序的集合。
  • jre<br>
    jre(Java Runtime Evironment)Java運(yùn)行時環(huán)境,是運(yùn)行Java程序的平臺,所有的Java程序必須在這個平臺中才能執(zhí)行。
  • jvm<br>
    jvm(Java Virtual Machine)Java虛擬機(jī),是用代碼虛擬出來的計算機(jī),模擬執(zhí)行計算機(jī)的各項功能,它有自己的硬件架構(gòu),如:處理器、堆棧、寄存器等,還有自己的一套指令系統(tǒng),在不同的操作系統(tǒng)上都可以安裝JVM,從而實現(xiàn)Java程序在不同的操作系統(tǒng)上都能執(zhí)行,JVM就是為實現(xiàn)Java的跨平臺特性。
    JVM加載類的過程
    我們執(zhí)行Java程序開發(fā)出來后,需要先編譯再執(zhí)行,JVM就負(fù)責(zé)加載類的過程。<br>
    類加載的過程分為:

    1. 加載
    2. 驗證
    3. 準(zhǔn)備
    4. 解析
    5. 初始化
      類加載的具體過程
      下面詳細(xì)介紹下這幾個過程:
    6. 加載<br>
      在加載類的過程要完成:
    7. 根據(jù)類的全名限定符,獲取class二進(jìn)制流,這個流可以從磁盤上的class、jar文件獲得,也可以從網(wǎng)絡(luò)中獲得。
    8. 將類的靜態(tài)存儲結(jié)構(gòu)轉(zhuǎn)化為方法區(qū)的運(yùn)行時動態(tài)存儲結(jié)構(gòu)
    9. 在內(nèi)存的堆中生成對應(yīng)的java.lang.Class對象,作為方法區(qū)的入口
    10. 驗證<br>
      加載類完成后,就進(jìn)入了驗證過程,這個過程保證了前面生成的Class對象中的信息,不會危害JVM的安全。<br>
      需要驗證的方面有:
    11. 文件格式驗證,是要驗證字節(jié)流是否符合Class文件格式的規(guī)范,并且能被當(dāng)前版本的虛擬機(jī)處理。如驗證魔數(shù)是否0xCAFEBABE;主、次版本號是否正在當(dāng)前虛擬機(jī)處理范圍之內(nèi);常量池的常量中是否有不被支持的常量類型等等,該驗證階段的主要目的是保證輸入的字節(jié)流能正確地解析并存儲于方法區(qū)中,經(jīng)過這個階段的驗證后,字節(jié)流才會進(jìn)入內(nèi)存的方法區(qū)中存儲,所以后面的三個驗證階段都是基于方法區(qū)的存儲結(jié)構(gòu)進(jìn)行的。
    12. 元數(shù)據(jù)驗證,是對字節(jié)碼描述的信息進(jìn)行語義分析,以保證其描述的信息符合Java語言規(guī)范的要求??赡馨ǖ尿炞C如:這個類是否有父類;這個類的父類是否繼承了不允許被繼承的類;如果這個類不是抽象類,是否實現(xiàn)了其父類或接口中要求實現(xiàn)的所有方法。
    13. 字節(jié)碼驗證,主要工作是進(jìn)行數(shù)據(jù)流和控制流分析,保證被校驗類的方法在運(yùn)行時不會做出危害虛擬機(jī)安全的行為。如果一個類方法體的字節(jié)碼沒有通過字節(jié)碼驗證,那肯定是有問題的;但如果一個方法體通過了字節(jié)碼驗證,也不能說明其一定就是安全的。
    14. 符號引用驗證,發(fā)生在虛擬機(jī)將符號引用轉(zhuǎn)化為直接引用的時候,這個轉(zhuǎn)化動作將在“解析階段”中發(fā)生。驗證符號引用中通過字符串描述的權(quán)限定名是否能找到對應(yīng)的類;在指定類中是否存在符合方法字段的描述符及簡單名稱所描述的方法和字段;符號引用中的類、字段和方法的訪問性(private、protected、public、default)是否可被當(dāng)前類訪問。
    15. 準(zhǔn)備<br>
      準(zhǔn)備階段會在方法區(qū)中為類的靜態(tài)變量分配內(nèi)存,并賦給默認(rèn)值。
      public static int count = 100;

      如:上面的count變量在準(zhǔn)備階段會賦值為0,在初始化時再賦值為100;

    16. 解析<br>
      解析階段是虛擬機(jī)將常量池內(nèi)的符號引用替換為直接引用的過程。
      • 符號引用(Symbolic Reference)<br>
        符號引用以一組符號來描述所引用的目標(biāo),符號可以是任何形式的字面量,只要使用時能無歧義地定位到目標(biāo)即可。符號引用與虛擬機(jī)實現(xiàn)的內(nèi)存布局無關(guān),引用的目標(biāo)并不一定已經(jīng)加載到內(nèi)存中。
      • 直接引用(Direct Reference)<br>
        直接引用可以是直接指向目標(biāo)的指針、相對偏移量或是一個能間接定位到目標(biāo)的句柄。直接引用是與虛擬機(jī)實現(xiàn)的內(nèi)存布局相關(guān)的,如果有了直接引用,那么引用的目標(biāo)必定已經(jīng)在內(nèi)存中存在。
    17. 初始化<br>
      類初始化是類加載過程的最后一步,前面的類加載過程,除了在加載階段用戶應(yīng)用程序可以通過自定義類加載器參與之外,其余動作完全由虛擬機(jī)主導(dǎo)和控制。到了初始化階段,才真正開始執(zhí)行類中定義的Java程序代碼。<br>
      初始化階段是執(zhí)行類構(gòu)造器<clinit>()方法的過程。<clinit>()方法是由編譯器自動收集類中的所有類變量的賦值動作和靜態(tài)語句塊(static{}塊)中的語句合并產(chǎn)生的。
      那么何時執(zhí)行初始化呢?
    18. 創(chuàng)建類的實例
    19. 訪問類的靜態(tài)變量(除常量外,final修飾的)
      原因:常量一種特殊的變量,因為編譯器把他們當(dāng)作值而不是屬性來對待。
    20. 訪問類的靜態(tài)方法
    21. 反射如(Class.forName("com.test.Person"))
    22. 當(dāng)初始化一個類時,發(fā)現(xiàn)其父類還未初始化,則先調(diào)用父類的初始化
    23. 虛擬機(jī)啟動時,定義了main()方法的那個類先初始化
      代碼案例
      了解了類的加載機(jī)制,我們來看一道面試題:

      public class MySingleton {
      private static MySingleton singleton = new MySingleton();
      public static int count1 = 0;
      public static int count2;
      
      private MySingleton(){
              count1++;
              count2++;
      }
      
      public static MySingleton getInstance(){
              return singleton;
      }
      
      public static void main(String[] args) {
              MySingleton singleton = MySingleton.getInstance();
              System.out.println("count1-->"+MySingleton.count1);
              System.out.println("count2-->"+MySingleton.count2);
      }
      }
      上面的結(jié)果,大多數(shù)同學(xué)可能認(rèn)為兩個靜態(tài)變量都是1,結(jié)果比較意外:

      count1-->0
      count2-->1

      這是為什么呢?下面我們來分析下:
    24. 首先我們知道在類的準(zhǔn)備階段會為靜態(tài)變量賦默認(rèn)值:<br>
      singleton = null;
      count1 = 0;
      count2 = 0;
    25. 當(dāng)調(diào)用類的靜態(tài)方法getInstance后,引發(fā)類的初始化,先執(zhí)行new MySingleton() 調(diào)用構(gòu)造方法,這時:<br>
      count1 = 1;
      count2 = 1;
    26. 繼續(xù)初始化,為變量賦值,count1賦值為0,count2沒有賦值就保留值1,結(jié)果就是:<br>
      count1 = 0;
      count2 = 1;
      總結(jié)
      JVM是代碼模擬的計算機(jī),有自己的硬件和軟件,JVM能實現(xiàn)Java類的加載和運(yùn)行,具體加載過程有:加載、驗證、準(zhǔn)備、解析、初始化5個步驟組成。

創(chuàng)新互聯(lián)www.cdcxhl.cn,專業(yè)提供香港、美國云服務(wù)器,動態(tài)BGP最優(yōu)骨干路由自動選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡(luò)助力業(yè)務(wù)部署。公司持有工信部辦法的idc、isp許可證, 機(jī)房獨(dú)有T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確進(jìn)行流量調(diào)度,確保服務(wù)器高可用性。佳節(jié)活動現(xiàn)已開啟,新人活動云服務(wù)器買多久送多久。

當(dāng)前文章:好程序員Java學(xué)習(xí)路線分享JVM類加載機(jī)制-創(chuàng)新互聯(lián)
本文鏈接:http://bm7419.com/article26/igdjg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供面包屑導(dǎo)航建站公司、全網(wǎng)營銷推廣、商城網(wǎng)站、營銷型網(wǎng)站建設(shè)企業(yè)建站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

商城網(wǎng)站建設(shè)