av激情亚洲男人的天堂国语,日韩欧美精品一中文字幕,无码av一区二区三区无码,国产又色又爽又刺激的a片,国产又色又爽又刺激的a片

JVM系列—Class文件加載過程

JVM系列筆記目錄
虛擬機的基礎(chǔ)概念class文件結(jié)構(gòu)class文件加載過程jvm內(nèi)存模型JVM常用指令GC與調(diào)優(yōu)

10余年專業(yè)網(wǎng)站制作公司歷程,堅持以創(chuàng)新為先導(dǎo)的網(wǎng)站服務(wù),服務(wù)超過近1000家企業(yè)及個人,涉及網(wǎng)站設(shè)計、成都App制作、微信開發(fā)、平面設(shè)計、互聯(lián)網(wǎng)整合營銷等多個領(lǐng)域。在不同行業(yè)和領(lǐng)域給人們的工作和生活帶來美好變化。

Class文件加載過程
JVM加載Class文件主要分3個過程:Loading 、Linking、Initialzing

1.Loading
Loading的過程就是通過類加載器將.class文件加載到j(luò)vm內(nèi)存中過程。需要理解雙親委派機制、類加載器ClassLoader,加載過程如下。

ClassLoader

不同的類加載器加載范圍不一樣,以Java8中的為例。

BootClassLoader 加載范圍sun.boot.class.pahtExtClassLoader 加載范圍java.ext.dirsAppClassLoader 加載范圍java.class.pathCustomClassLoader 可自定義加載范圍

前三個加載器來自JDK的Launcher類,三個ClassLoader作為Launcher的內(nèi)部類,感興趣可以查看下源碼。

開發(fā)者也可以自定義的ClassLoader,自定義記載范圍。

雙親委派機制

自底向上檢查該類是否已經(jīng)加載,parent方向;自頂向下進行類的實際查找和加載,child方向。 類的加載遵循雙親委派機制,主要是出于安全的考慮。雙親委派機制是如何實現(xiàn)的,下面源碼會解釋。

? 注意:雙親委派中存在所謂的父加載器并不是加載器的加載器,只是翻譯的問題,別混淆了類的繼承概念。

ClassLoader源碼

ClassLoader源碼中比較重要的一個函數(shù)是loadClass(),執(zhí)行過程是:findLoadedClass()->parrent.loadClass()->findClass(),第一步是自底向上查詢是否已經(jīng)加載,第二步是自頂向下查找加載類。這里就規(guī)定或是說實現(xiàn)了雙親委派機制。詳細(xì)見ClassLoader的源碼。

自定義ClassLoader

如何自定義ClassLoader?可以繼承ClassLoader類,重新自己的findClass(),在里面調(diào)用defineClass()來實現(xiàn)自定義加載特定范圍的類。

如何打破雙親委派機制,哪種情形下打破過?

從上面的ClassLoader源碼中大概能看出是如何實現(xiàn)了雙親委派機制的,從這入手可以通過2種方式打破該機制:

super(parent)指定parent會打破該機制自定義ClassLoader重寫loadClass()也可以打破

何時打破過?雙親委派機制并不是不能打破,某些特殊場景下也會選擇打破該機制。

JDK 1.2之前,自定義ClassLoader必須重寫loadClass(),打破過。線程ThreadContextClassLoader可以實現(xiàn)基礎(chǔ)類調(diào)用實現(xiàn)類代碼,通過thread.setContextClassLoader指定。熱啟動熱部署,如tomcat都有自己模塊指定的classloader,可以加載同一類庫的不同版本。

Class執(zhí)行方式

Class執(zhí)行方式分為3種:解釋執(zhí)行、編譯執(zhí)行、混合執(zhí)行,各有優(yōu)缺點,可通過參數(shù)指定。

1.解釋執(zhí)行:使用bytecode intepreter 解釋器解釋執(zhí)行,該模式啟動很快,執(zhí)行稍慢,可通過-Xint參數(shù)指定該模式。
2.編譯執(zhí)行:使用 Just in time Complier JIT編譯器編譯執(zhí)行,該模式執(zhí)行很快,編譯很慢,可通過-Xcomp參數(shù)指定該模式。
3.混合執(zhí)行:默認(rèn)的模式,解釋器+熱點代碼編譯,開始解釋執(zhí)行,啟動較快,對熱點代碼進行實時監(jiān)測和編譯成本地代碼執(zhí)行,可通過-Xmixed參數(shù)指定該模式。
熱點代碼監(jiān)測:多次被調(diào)用的方法用方法計數(shù)器,多次被調(diào)用的循環(huán)用循環(huán)計數(shù)器,可通過參數(shù)-XX:CompileThreshold = 10000指定觸發(fā)JIT編譯的閾值。

2.Linking
Linking鏈接的過程分3個階段:Vertification、Preparation、Resolution。

  • Vertification: 驗證Class文件是否符合JVM規(guī)定。
  • Preparation:給靜態(tài)成員變量賦默認(rèn)值
  • Resolution:將類、方法、屬性等符號引用解釋為直接引用;常量池中的各種符號引用解釋為指針、偏移量等內(nèi)存地址的直接引用

3. Initializing
調(diào)用初始化代碼clint,給靜態(tài)成員變量賦初始值。

這里可以了解下必須初始化的5種情況:

new getstatic putstatic invokestatic指令,訪問final變量除外java.lang.reflect對類進行反射調(diào)用時初始化子類的時候,父類必須初始化虛擬機啟動時,被執(zhí)行的主類必須初始化動態(tài)語言支持java.lang.invoke.MethodHandler解釋的結(jié)果為REF_getstatic REF_putstatic REF_invokestatic的方法句柄時,該類必須初始化。

4.總結(jié)思考
設(shè)計模式中單例模式的雙重檢查的實現(xiàn),INSTANCE是否需要加valatile?

 
 
 
 
  1. public class Mgr06 { 
  2.     // 是否需要加volatile? 
  3.     private static volatile Mgr06 INSTANCE; 
  4.  
  5.     private Mgr06() { 
  6.     } 
  7.  
  8.     public static Mgr06 getInstance() { 
  9.         if (INSTANCE == null) { 
  10.             //雙重檢查 
  11.             synchronized (Mgr06.class) { 
  12.                 if(INSTANCE == null) { 
  13.                     try { 
  14.                         Thread.sleep(1); 
  15.                     } catch (InterruptedException e) { 
  16.                         e.printStackTrace(); 
  17.                     } 
  18.                     // new 了對象,不為null,但未完成變量的初始化復(fù)制,對象處于半初始化狀                    態(tài),其它線程有可能取到半初始化的對象。 
  19.                     INSTANCE = new Mgr06(); 
  20.                 } 
  21.             } 
  22.         } 
  23.         return INSTANCE; 
  24.     } 
  25. 復(fù)制代碼 

個人認(rèn)為是需要加的。思考方向, class文件load到內(nèi)存,給靜態(tài)變量賦默認(rèn)值,再賦初始值,new 對象的時候,首先要申請內(nèi)存空間,然后給成員變量賦默認(rèn)值,接下來給成員變量賦初始值,這個過程中對象有可能處于半初始化狀態(tài),多線程并發(fā)下別的線程有可能取到半初始化的對象,加volatile可保證線程的可見性。


當(dāng)前文章:JVM系列—Class文件加載過程
當(dāng)前URL:http://uogjgqi.cn/article/dpphipg.html
掃二維碼與項目經(jīng)理溝通

我們在微信上24小時期待你的聲音

解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流