javaJVM_虛擬機_類加載器

https://www.cnblogs.com/prayers/p/5515245.html
https://www.cnblogs.com/eastday/p/8124580.html
https://www.cnblogs.com/IUbanana/p/7067362.html
http://www.cnblogs.com/ityouknow/p/5603287.html
http://www.importnew.com/25295.html

一窍蓝、java虛擬機的生命周期

虛擬機存在的目的是讓java程序能夠正常運行妓羊,所以它的生命周期也是伴隨著java程序的初始化與終止。服務(wù)器上有多少個java程序正在運行尚困,就有多少個java虛擬機在維護這個程序。
java虛擬機的初始化以java程序main方法作為入口讶迁,main方法必須是public static void 并以字符串數(shù)組作為參數(shù)亿鲜,可以不適用main作為方法名吻贿,但是必須在虛擬機中配置好。main方法被初始線程初始化為初始化線程呻右。
java線程分為守護線程與普通線程跪妥,守護線程是java虛擬機的線程,負責(zé)守護普通線程的正常運行声滥,例如垃圾回收線程眉撵。
普通線程為java程序內(nèi)的線程,當所有普通線程執(zhí)行完畢結(jié)束落塑,則java虛擬機生命周期結(jié)束纽疟。
通過thread.setDaemon(true)可以將普通線程設(shè)置為守護線程

public class JAVAtest {

    public static void main(String[] args) {
        Thread thread = new Thread(){
            @Override
            public void run() {
                System.out.println("守護開始");
                for (int i = 0 ; i < 100 ; i ++) {
                    try {
                        Thread.sleep(100) ;
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.out.println(i);
                }
            }
        };
//        thread.setDaemon(true);
        thread.start();

        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println(12);
            }
        };
        Thread thread1 = new Thread(runnable);
        thread1.start();
    }
}

二、java虛擬機的體系結(jié)構(gòu)

1.類加載器子系統(tǒng):負責(zé)加載程序中的類型(類和接口)
2.執(zhí)行引擎:負責(zé)執(zhí)行被加載類中包含的指令
3.運行時數(shù)據(jù)區(qū):負責(zé)保存字節(jié)碼憾赁、被加載類的其他額外信息

三污朽、類加載器子系統(tǒng)

1.類的唯一性:

對于任意一個類,都需要由加載它的類加載器和類的全限定名一同確定其在Java虛擬機中的唯一性龙考。(此處的類加載器由于采用雙親委派模型蟆肆,所以真正加載類的可能并不是你所使用的類加載器,例如兩個自定義類加載器繼承了ClassLoader晦款,所以加載類的為同一個頂層類加載器)每一個類被加載為Class類的實例炎功,類加載器對象與class對象都保存在堆中,類信息保存在方法區(qū)中缓溅。

2.類加載器:
2.1類加載器類別:

從java虛擬機的角度劃分:
a.啟動類加載器(Bootstrap ClassLoader):這個類加載器使用C++語言實現(xiàn)蛇损,是虛擬機自身的一部分。
b.其他的類加載器:這些類加載器由Java語言實現(xiàn)坛怪,獨立于虛擬機州藕,并且全部都繼承自抽象類java.lang.ClassLoader。

從java繼承級別劃分:
a.啟動類加載器(Bootstrap ClassLoader):虛擬機的一部分酝陈,由c++編寫。這個類加載器負責(zé)將存放在<JAVA_HOME>\lib目錄中毁涉,或者被-Xbootclasspath虛擬機參數(shù)指定的路徑中沉帮,并且是虛擬機識別的類庫加載到虛擬機內(nèi)存中。
b.擴展類加載器(Extension ClassLoader):該加載器器是用JAVA編寫,且它的父類加載器是Bootstrap穆壕,是由sun.misc.Launcher$ExtClassLoader實現(xiàn)的待牵,主要加載JAVA_HOME/lib/ext目錄中的類庫。開發(fā)者可以這幾使用擴展類加載器喇勋。
c.應(yīng)用程序類加載器(Application ClassLoader):由于這個類加載器是ClassLoader中的getSystemClassLoader()方法的返回值缨该,所以一般也稱為系統(tǒng)類加載器。它負責(zé)加載用戶類路徑(ClassPath)上所指定的類庫川背,開發(fā)者可以直接使用這個類加載器贰拿,如果應(yīng)用程序中沒有自定義過自己的類加載器,一般情況下這個就是程序中默認的類加載器熄云。

注意:類加載器的體系并不是“繼承”體系膨更,而是委派體系,大多數(shù)類加載器首先會到自己的parent中查找類或者資源缴允,如果找不到才會到自己本地查找荚守。類加載器的委托行為動機是為了避免相同的類被加載多次。

2.3雙親委派模型:
image.png
image.png

類加載器之間的層次關(guān)系练般,稱為類加載器的雙親委派模型矗漾。雙親委派模型要求除了頂層的啟動類加載器外,其余類加載器都應(yīng)該有自己的父類加載器薄料。注意敞贡,這里類加載器之間的父子關(guān)系一般不會以繼承的關(guān)系實現(xiàn),而是使用組合關(guān)系來復(fù)用父加載器的代碼都办。

2.4雙親委派模型的工作過程:

如果一個類加載器收到了類加載的請求嫡锌,它首先不會自己去嘗試加載這個類,而是把這個請求委派給父類加載器去完成琳钉,每一個層次的類加載器都是如此势木,因此所有的加載請求最終都應(yīng)該首先傳送到頂層的啟動類加載器中,只有當父加載器反饋自己無法完成這個加載請求時歌懒,子加載器才會嘗試自己去加載啦桌。

2.5雙親委派模型的實現(xiàn)

類加載器均是繼承自java.lang.ClassLoader抽象類。首先及皂,我們看一看java.lang.ClassLoader類的loadClass()方法:

protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        synchronized (getClassLoadingLock(name)) {//對加載類的過程進行同步
            // 首先甫男,檢查請求的類是否已經(jīng)被加載過了
            // First, check if the class has already been loaded
            Class c = findLoadedClass(name);
            if (c == null) {
                long t0 = System.nanoTime();
                try {
                    if (parent != null) {
                        c = parent.loadClass(name, false);//委派請求給父加載器
                    } else {
                        //父加載器為null,說明this為擴展類加載器的實例验烧,父加載器為啟動類加載器
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // 如果父加載器拋出ClassNotFoundException
                    // 說明父加載器無法完成加載請求
                    // ClassNotFoundException thrown if class not found
                    // from the non-null parent class loader
                }
 
                if (c == null) {
                    // 如果父加載器無法加載
                    // 調(diào)用本身的findClass方法來進行類加載
                    // If still not found, then invoke findClass in order
                    // to find the class.
                    long t1 = System.nanoTime();
                    c = findClass(name);
 
                    // this is the defining class loader; record the stats
                    sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                    sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                    sun.misc.PerfCounter.getFindClasses().increment();
                }
            }
            if (resolve) {
                resolveClass(c);
            }
            return c;
        }
    }

通過進一步分析標準擴展類加載器(sun.misc.LauncherExtClassLoader)和系統(tǒng)類加載器(sun.misc.LauncherAppClassLoader)的代碼以及其公共父類(java.net.URLClassLoader和java.security.SecureClassLoader)的代碼可以看出板驳,都沒有重寫java.lang.ClassLoader中默認的委派加載規(guī)則——loadClass(…)方法。所以這些類加載器都沿用了ClassLoader的雙親委派規(guī)則

2.6雙親委派模型的優(yōu)點

a.安全性:通過使用雙親委派模型碍拆,同一個類由不同的類加載器加載出來仍然是同一個類若治,不會出現(xiàn)使java程序出現(xiàn)混亂慨蓝。避免類被重復(fù)加載

3.類加載機制

加載 — 驗證 — 準備 — 解析 — 初始化
加載:通過一個類的全限定名獲取其對應(yīng)的二進制流,將二進制流內(nèi)類的靜態(tài)存儲結(jié)構(gòu)轉(zhuǎn)變?yōu)榉椒▍^(qū)中的運行時數(shù)據(jù)結(jié)構(gòu)端幼。在java堆中生成一個代表這個類的對象礼烈,作為方法區(qū)對應(yīng)數(shù)據(jù)的入口。(這個階段可控性是最高的婆跑,因為可以在此階段選擇加載類的類加載器)
注意此時堆中的對象為類對象此熬。

驗證:為了確保class文件字節(jié)流中包含的信息符合虛擬機的要求,不會對虛擬機造成威脅滑进。
準備:為方法區(qū)中的靜態(tài)數(shù)據(jù)初始化犀忱,此時的初始化是初始化null,0郊供,等默認值峡碉,如果數(shù)據(jù)被final static修飾,則初始化指定值驮审。
解析:把類中的符號引用轉(zhuǎn)變?yōu)橹苯右?br> 初始化:根據(jù)程序執(zhí)行類構(gòu)造器<client>鲫寄,為類變量賦值。構(gòu)造器方法是由編譯器自動收集類中的類變量的賦值操作和靜態(tài)語句塊中的語句合并而成的疯淫。

以下不會觸發(fā)初始化:
1.通過子類引用父類的靜態(tài)字段地来,只會觸發(fā)父類的初始化,而不會觸發(fā)子類的初始化熙掺。
2.定義對象數(shù)組未斑,不會觸發(fā)該類的初始化。
3.常量在編譯期間會存入調(diào)用類的常量池中币绩,本質(zhì)上并沒有直接引用定義常量的類蜡秽,不會觸發(fā)定義常量所在的類。
4.通過類名獲取Class對象缆镣,不會觸發(fā)類的初始化芽突。
5.通過Class.forName加載指定類時,如果指定參數(shù)initialize為false時董瞻,也不會觸發(fā)類初始化寞蚌,其實這個參數(shù)是告訴虛擬機,是否要對類進行初始化钠糊。
6.通過ClassLoader默認的loadClass方法挟秤,也不會觸發(fā)初始化動作。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末抄伍,一起剝皮案震驚了整個濱河市艘刚,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌截珍,老刑警劉巖昔脯,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件啄糙,死亡現(xiàn)場離奇詭異,居然都是意外死亡云稚,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門沈堡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來静陈,“玉大人,你說我怎么就攤上這事诞丽【ㄓ担” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵僧免,是天一觀的道長刑赶。 經(jīng)常有香客問我,道長懂衩,這世上最難降的妖魔是什么撞叨? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮浊洞,結(jié)果婚禮上牵敷,老公的妹妹穿的比我還像新娘。我一直安慰自己法希,他們只是感情好枷餐,可當我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著苫亦,像睡著了一般毛肋。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上屋剑,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天润匙,我揣著相機與錄音,去河邊找鬼饼丘。 笑死趁桃,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的肄鸽。 我是一名探鬼主播卫病,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼典徘!你這毒婦竟也來了蟀苛?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤逮诲,失蹤者是張志新(化名)和其女友劉穎帜平,沒想到半個月后幽告,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡裆甩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年冗锁,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嗤栓。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡冻河,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出茉帅,到底是詐尸還是另有隱情叨叙,我是刑警寧澤,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布堪澎,位于F島的核電站擂错,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏樱蛤。R本人自食惡果不足惜钮呀,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望刹悴。 院中可真熱鬧行楞,春花似錦、人聲如沸土匀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽就轧。三九已至证杭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間妒御,已是汗流浹背解愤。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留乎莉,地道東北人送讲。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像惋啃,于是被迫代替她去往敵國和親哼鬓。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,055評論 2 355