Java類加載機(jī)制

1.虛擬機(jī)如何加載這些Class文件?(類加載的過(guò)程)
2.Class文件中的信息進(jìn)入到虛擬機(jī)后會(huì)發(fā)生什么變化?

Java虛擬機(jī)把描述類的數(shù)據(jù)從Class文件加載到內(nèi)存访忿,并對(duì)數(shù)據(jù)進(jìn)行校驗(yàn)细疚、轉(zhuǎn)換解析和初始化毕莱,最終形成可以被虛擬機(jī)直接使用的Java類型储耐,這就是虛擬機(jī)的加載機(jī)制动分。

類從被加載到虛擬機(jī)內(nèi)存中開(kāi)始郑气,到卸載出內(nèi)存為止怠堪,它的整個(gè)生命周期包括了:加載(Loading)芽偏、驗(yàn)證(Verification)雷逆、準(zhǔn)備(Preparation)、解析(Resolution)哮针、初始化(Initialization)关面、使用(using)坦袍、和卸載(Unloading)七個(gè)階段。其中驗(yàn)證等太、準(zhǔn)備和解析三個(gè)部分統(tǒng)稱為連接(Linking)捂齐,這七個(gè)階段的發(fā)生順序如下圖所示:

如上圖所示,加載缩抡、驗(yàn)證奠宜、準(zhǔn)備、初始化和卸載這五個(gè)階段的順序是確定的瞻想,類的加載過(guò)程必須按照這個(gè)順序來(lái)按部就班地開(kāi)始压真,而解析階段則不一定,它在某些情況下可以在初始化階段后再開(kāi)始蘑险。

類的生命周期的每一個(gè)階段通常都是互相交叉混合式進(jìn)行的滴肿,通常會(huì)在一個(gè)階段執(zhí)行的過(guò)程中調(diào)用或激活另外一個(gè)階段。

一佃迄、類加載的時(shí)機(jī)

主動(dòng)引用:一個(gè)類被主動(dòng)引用之后會(huì)觸發(fā)初始化過(guò)程(加載泼差,驗(yàn)證,準(zhǔn)備需再此之前開(kāi)始)

必須馬上對(duì)類進(jìn)行初始化

1)遇到new呵俏、getstatic堆缘、putstatic或invokestatic這4條字節(jié)碼指令時(shí),如果類沒(méi)有進(jìn)行過(guò)初始化普碎,則需要先觸發(fā)其初始化吼肥。生成這4條指令最常見(jiàn)的Java代碼場(chǎng)景是:使用new關(guān)鍵字實(shí)例化對(duì)象時(shí)、讀取或者設(shè)置一個(gè)類的靜態(tài)字段(被final修飾麻车、已在編譯器把結(jié)果放入常量池的靜態(tài)字段除外)時(shí)缀皱、以及調(diào)用一個(gè)類的靜態(tài)方法的時(shí)候。

2)使用java.lang.reflect包的方法對(duì)類進(jìn)行反射調(diào)用的時(shí)候绪氛,如果類沒(méi)有進(jìn)行過(guò)初始化唆鸡,則需要先觸發(fā)其初始化涝影。

3)當(dāng)初始化一個(gè)類的時(shí)候枣察,如果發(fā)現(xiàn)其父類還沒(méi)有進(jìn)行過(guò)初始化,則需要觸發(fā)父類的初始化燃逻。

4)當(dāng)虛擬機(jī)啟動(dòng)時(shí)序目,用戶需要指定一個(gè)執(zhí)行的主類(包含main()方法的類),虛擬機(jī)會(huì)先初始化這個(gè)類伯襟。

5)當(dāng)使用jdk7+的動(dòng)態(tài)語(yǔ)言支持時(shí)猿涨,如果java.lang.invoke.MethodHandle實(shí)例最后的解析結(jié)果REF_getStatic、REF_putStatic姆怪、REF_invokeStatic的方法句柄叛赚,并且這個(gè)方法句柄所對(duì)應(yīng)的類沒(méi)有進(jìn)行過(guò)初始化澡绩,則需要先觸發(fā)器初始化。

被動(dòng)引用:一個(gè)類如果是被動(dòng)引用的話俺附,該類不會(huì)觸發(fā)初始化過(guò)程

1)通過(guò)子類引用父類的靜態(tài)字段肥卡,不會(huì)導(dǎo)致子類初始化。對(duì)于靜態(tài)字段事镣,只有直接定義該字段的類才會(huì)被初始化步鉴,因此當(dāng)我們通過(guò)子類來(lái)引用父類中定義的靜態(tài)字段時(shí),只會(huì)觸發(fā)父類的初始化璃哟,而不會(huì)觸發(fā)子類的初始化氛琢。 只有定義了這個(gè)字段的類才會(huì)被初始化

2)通過(guò)數(shù)組定義來(lái)引用類,不會(huì)觸發(fā)此類的初始化随闪。

3)常量在編譯階段會(huì)存入調(diào)用類的常量池中阳似,本質(zhì)上沒(méi)有直接引用到定義常量的類,因此不會(huì)觸發(fā)定義常量的類的初始化铐伴。

二障般、類加載過(guò)程

1、加載

在加載階段盛杰,虛擬機(jī)需要完成以下三件事情:

1.通過(guò)一個(gè)類的全限定名來(lái)獲取定義此類的二進(jìn)制字節(jié)流挽荡。

2.將這個(gè)字節(jié)流所代表的靜態(tài)存儲(chǔ)結(jié)構(gòu)轉(zhuǎn)化為方法區(qū)的運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu)。

3.在java堆中生成一個(gè)代表這個(gè)類的java.lang.Class對(duì)象即供,作為方法區(qū)這些數(shù)據(jù)的訪問(wèn)入口定拟。

相對(duì)于類加載過(guò)程的其他階段,加載階段是開(kāi)發(fā)期相對(duì)來(lái)說(shuō)可控性比較強(qiáng)逗嫡,該階段既可以使用系統(tǒng)提供的類加載器完成青自,也可以由用戶自定義的類加載器來(lái)完成,開(kāi)發(fā)人員可以通過(guò)定義自己的類加載器去控制字節(jié)流的獲取方式驱证。

2延窜、驗(yàn)證

驗(yàn)證的目的是為了確保Class文件中的字節(jié)流包含的信息符合當(dāng)前虛擬機(jī)的要求,而且不會(huì)危害虛擬機(jī)自身的安全抹锄。不同的虛擬機(jī)對(duì)類驗(yàn)證的實(shí)現(xiàn)可能會(huì)有所不同逆瑞,但大致都會(huì)完成以下四個(gè)階段的驗(yàn)證:文件格式的驗(yàn)證、元數(shù)據(jù)的驗(yàn)證伙单、字節(jié)碼驗(yàn)證和符號(hào)引用驗(yàn)證获高。

1)文件格式的驗(yàn)證:驗(yàn)證字節(jié)流是否符合Class文件格式的規(guī)范,并且能被當(dāng)前版本的虛擬機(jī)處理吻育,該驗(yàn)證的主要目的是保證輸入的字節(jié)流能正確地解析并存儲(chǔ) 于方法區(qū)之內(nèi)念秧。經(jīng)過(guò)該階段的驗(yàn)證后,字節(jié)流才會(huì)進(jìn)入內(nèi)存的方法區(qū)中進(jìn)行存儲(chǔ)布疼,后面的三個(gè)驗(yàn)證都是基于方法區(qū)的存儲(chǔ)結(jié)構(gòu)進(jìn)行的摊趾。

2)元數(shù)據(jù)驗(yàn)證:對(duì)類的元數(shù)據(jù)信息進(jìn)行語(yǔ)義校驗(yàn)(其實(shí)就是對(duì)類中的各數(shù)據(jù)類型進(jìn)行語(yǔ)法校驗(yàn))币狠,保證不存在不符合Java語(yǔ)法規(guī)范的元數(shù)據(jù)信息。

3)字節(jié)碼驗(yàn)證:該階段驗(yàn)證的主要工作是進(jìn)行數(shù)據(jù)流和控制流分析砾层,對(duì)類的方法體進(jìn)行校驗(yàn)分析总寻,以保證被校驗(yàn)的類的方法在運(yùn)行時(shí)不會(huì)做出危害虛擬機(jī)安全的行為。

4)符號(hào)引用驗(yàn)證:這是最后一個(gè)階段的驗(yàn)證梢为,它發(fā)生在虛擬機(jī)將符號(hào)引用轉(zhuǎn)化為直接引用的時(shí)候(解析階段中發(fā)生該轉(zhuǎn)化渐行,后面會(huì)有講解),主要是對(duì)類自身以外的信息(常量池中的各種符號(hào)引用)進(jìn)行匹配性的校驗(yàn)铸董。

3祟印、準(zhǔn)備

準(zhǔn)備階段是正式為類變量分配內(nèi)存并設(shè)置類變量初始值的階段,這些內(nèi)存都將在方法區(qū)中進(jìn)行分配粟害。

注:

1)這時(shí)候進(jìn)行內(nèi)存分配的僅包括類變量(static)蕴忆,而不包括實(shí)例變量,實(shí)例變量會(huì)在對(duì)象實(shí)例化時(shí)隨著對(duì)象一塊分配在Java堆中悲幅。

2)這里所設(shè)置的初始值通常情況下是數(shù)據(jù)類型默認(rèn)的零值(如0套鹅、0L、null汰具、false等)卓鹿,而不是被在Java代碼中被顯式地賦予的值。

  1. 如果類字段的字段屬性表中存在ConstantValue屬性,在準(zhǔn)備階段該字段就會(huì)被初始化為ConstantValue所指定的值. final

4留荔、解析

解析階段是虛擬機(jī)將常量池內(nèi)的符號(hào)引用替換為直接引用的過(guò)程吟孙。

符號(hào)引用(Symbolic Reference):符號(hào)引用以一組符號(hào)來(lái)描述所引用的目標(biāo),符號(hào)引用可以是任何形式的字面量聚蝶,符號(hào)引用與虛擬機(jī)實(shí)現(xiàn)的內(nèi)存布局無(wú)關(guān)杰妓,引用的目標(biāo)并不一定已經(jīng)在內(nèi)存中。

直接引用(Direct Reference):直接引用可以是直接指向目標(biāo)的指針碘勉、相對(duì)偏移量或是一個(gè)能間接定位到目標(biāo)的句柄巷挥。直接引用是與虛擬機(jī)實(shí)現(xiàn)的內(nèi)存布局相關(guān)的,同一個(gè)符號(hào)引用在不同的虛擬機(jī)實(shí)例上翻譯出來(lái)的直接引用一般都不相同验靡,如果有了直接引用倍宾,那引用的目標(biāo)必定已經(jīng)在內(nèi)存中存在。

1晴叨、類或接口的解析:判斷所要轉(zhuǎn)化成的直接引用是對(duì)數(shù)組類型凿宾,還是普通的對(duì)象類型的引用,從而進(jìn)行不同的解析兼蕊。 加載引用的類

2、字段解析:對(duì)字段進(jìn)行解析時(shí)件蚕,會(huì)先在本類中查找是否包含有簡(jiǎn)單名稱和字段描述符都與目標(biāo)相匹配的字段孙技,如果有产禾,則查找結(jié)束;如果沒(méi)有牵啦,則會(huì)按照繼承關(guān)系從上往下遞歸搜索該類所實(shí)現(xiàn)的各個(gè)接口和它們的父接口亚情,還沒(méi)有,則按照繼承關(guān)系從上往下遞歸搜索其父類哈雏,直至查找結(jié)束楞件。 (注意查找順序)

3、類方法解析:對(duì)類方法的解析與對(duì)字段解析的搜索步驟差不多裳瘪,只是多了判斷該方法所處的是類還是接口的步驟土浸,而且對(duì)類方法的匹配搜索,是先搜索父類彭羹,再搜索接口黄伊。

4、接口方法解析:與類方法解析步驟類似派殷,只是接口不會(huì)有父類还最,因此,只遞歸向上搜索父接口就行了毡惜。

5拓轻、初始化

類初始化階段是類加載過(guò)程的最后一步,前面的類加載過(guò)程中经伙,除了加載(Loading)階段用戶應(yīng)用程序可以通過(guò)自定義類加載器參與之外悦即,其余動(dòng)作完全由虛擬機(jī)主導(dǎo)和控制。到了初始化階段橱乱,才真正開(kāi)始執(zhí)行類中定義的Java程序代碼辜梳。

初始化階段是執(zhí)行類構(gòu)造器()方法的過(guò)程。

1)<clinit>()方法是由編譯器自動(dòng)收集類中的所有類變量的賦值動(dòng)作和靜態(tài)語(yǔ)句塊(static{}塊)中的語(yǔ)句合并產(chǎn)生的泳叠,編譯器收集的順序由語(yǔ)句在源文件中出現(xiàn)的順序所決定作瞄。(靜態(tài)語(yǔ)句塊中只能賦值,不能訪問(wèn),靜態(tài)語(yǔ)句塊只能訪問(wèn)到定義在靜態(tài)語(yǔ)句塊之前的變量)

2)<clinit>()方法與類的構(gòu)造函數(shù)不同,它不需要顯式地調(diào)用父類構(gòu)造器危纫,虛擬機(jī)會(huì)保證在子類的<clinit>()方法執(zhí)行之前宗挥,父類的()方法已經(jīng)執(zhí)行完畢,因此在虛擬機(jī)中第一個(gè)執(zhí)行的<clinit>()方法的類一定是java.lang.Object种蝶。

3)由于父類的<clinit>()方法先執(zhí)行契耿,也就意味著父類中定義的靜態(tài)語(yǔ)句塊要優(yōu)先于子類的變量賦值操作。

4)<clinit>()方法對(duì)于類或者接口來(lái)說(shuō)并不是必需的螃征,如果一個(gè)類中沒(méi)有靜態(tài)語(yǔ)句塊也沒(méi)有對(duì)變量的賦值操作搪桂,那么編譯器可以不為這個(gè)類生成<clinit>()方法。

5)接口中可能會(huì)有變量賦值操作,因此接口也會(huì)生成<clinit>()方法踢械。但是接口與類不同酗电,執(zhí)行接口的<clinit>()方法不需要先執(zhí)行父接口的<clinit>()方法。只有當(dāng)父接口中定義的變量被使用時(shí)内列,父接口才會(huì)被初始化撵术。另外,接口的實(shí)現(xiàn)類在初始化時(shí)也不會(huì)執(zhí)行接口的<clinit>()方法话瞧。

6)虛擬機(jī)會(huì)保證一個(gè)類的()方法在多線程環(huán)境中被正確地加鎖和同步嫩与。如果有多個(gè)線程去同時(shí)初始化一個(gè)類,那么只會(huì)有一個(gè)線程去執(zhí)行這個(gè)類的<clinit>()方法交排,其它線程都需要阻塞等待划滋,直到活動(dòng)線程執(zhí)行<clinit>()方法完畢。如果在一個(gè)類的<clinit>()方法中有耗時(shí)很長(zhǎng)的操作个粱,那么就可能造成多個(gè)進(jìn)程阻塞古毛。

類加載器

通過(guò)一個(gè)類的全限定名來(lái)獲取描述此類的二進(jìn)制字節(jié)流

類與類加載器

類名稱空間,比較兩個(gè)類是否相等,只有在這兩個(gè)類是由同一個(gè)類加載器加載的前提下才有意義.

三都许、雙親委派模型

JVM預(yù)定義的三種類型類加載器:

1)啟動(dòng)(Bootstrap)類加載器:是用本地代碼實(shí)現(xiàn)的類裝入器稻薇,它負(fù)責(zé)將 /lib下面的類庫(kù)加載到內(nèi)存中(比如rt.jar)。由于引導(dǎo)類加載器涉及到虛擬機(jī)本地實(shí)現(xiàn)細(xì)節(jié)胶征,開(kāi)發(fā)者無(wú)法直接獲取到啟動(dòng)類加載器的引用塞椎,所以不允許直接通過(guò)引用進(jìn)行操作。

2)標(biāo)準(zhǔn)擴(kuò)展(Extension)類加載器:是由 Sun 的 ExtClassLoader(sun.misc.Launcher$ExtClassLoader)實(shí)現(xiàn)的睛低。它負(fù)責(zé)將< Java_Runtime_Home >/lib/ext或者由系統(tǒng)變量 java.ext.dir指定位置中的類庫(kù)加載到內(nèi)存中案狠。開(kāi)發(fā)者可以直接使用標(biāo)準(zhǔn)擴(kuò)展類加載器。

3)系統(tǒng)(System)類加載器:是由 Sun 的 AppClassLoader(sun.misc.Launcher$AppClassLoader)實(shí)現(xiàn)的钱雷。它負(fù)責(zé)將系統(tǒng)類路徑(CLASSPATH)中指定的類庫(kù)加載到內(nèi)存中骂铁。開(kāi)發(fā)者可以直接使用系統(tǒng)類加載器。

雙親委派機(jī)制描述:

某個(gè)特定的類加載器在接到加載類的請(qǐng)求時(shí)罩抗,首先將加載任務(wù)委托給父類加載器拉庵,依次遞歸,如果父類加載器可以完成類加載任務(wù)套蒂,就成功返回钞支;只有父類加載器無(wú)法完成此加載任務(wù)時(shí),才自己去加載操刀。

    /**
     * Loads the class with the specified <a href="#name">binary name</a>.  The
     * default implementation of this method searches for classes in the
     * following order:
     *
     * <p><ol>
     *
     *   <li><p> Invoke {@link #findLoadedClass(String)} to check if the class
     *   has already been loaded.  </p></li>
     *
     *   <li><p> Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method
     *   on the parent class loader.  If the parent is <tt>null</tt> the class
     *   loader built-in to the virtual machine is used, instead.  </p></li>
     *
     *   <li><p> Invoke the {@link #findClass(String)} method to find the
     *   class.  </p></li>
     *
     * </ol>
     *
     * <p> If the class was found using the above steps, and the
     * <tt>resolve</tt> flag is true, this method will then invoke the {@link
     * #resolveClass(Class)} method on the resulting <tt>Class</tt> object.
     *
     * <p> Subclasses of <tt>ClassLoader</tt> are encouraged to override {@link
     * #findClass(String)}, rather than this method.  </p>
     *
     * <p> Unless overridden, this method synchronizes on the result of
     * {@link #getClassLoadingLock <tt>getClassLoadingLock</tt>} method
     * during the entire class loading process.
     *
     * @param  name
     *         The <a href="#name">binary name</a> of the class
     *
     * @param  resolve
     *         If <tt>true</tt> then resolve the class
     *
     * @return  The resulting <tt>Class</tt> object
     *
     * @throws  ClassNotFoundException
     *          If the class could not be found
     */
    protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        synchronized (getClassLoadingLock(name)) {
            // 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 {
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // ClassNotFoundException thrown if class not found
                    // from the non-null parent class loader
                }

                if (c == null) {
                    // 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;
        }
    }

1.檢查類是否已經(jīng)被加載
2.如果沒(méi)有烁挟,就用父類的加載器
3.如果父類無(wú)法加載,然后調(diào)用findClass方法自行加載

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末骨坑,一起剝皮案震驚了整個(gè)濱河市撼嗓,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖静稻,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件警没,死亡現(xiàn)場(chǎng)離奇詭異匈辱,居然都是意外死亡振湾,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門(mén)亡脸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)押搪,“玉大人,你說(shuō)我怎么就攤上這事浅碾〈笾荩” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵垂谢,是天一觀的道長(zhǎng)厦画。 經(jīng)常有香客問(wèn)我,道長(zhǎng)滥朱,這世上最難降的妖魔是什么根暑? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮徙邻,結(jié)果婚禮上排嫌,老公的妹妹穿的比我還像新娘。我一直安慰自己缰犁,他們只是感情好淳地,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著帅容,像睡著了一般颇象。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上并徘,一...
    開(kāi)封第一講書(shū)人閱讀 52,156評(píng)論 1 308
  • 那天遣钳,我揣著相機(jī)與錄音,去河邊找鬼饮亏。 笑死耍贾,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的路幸。 我是一名探鬼主播荐开,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼简肴!你這毒婦竟也來(lái)了晃听?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎能扒,沒(méi)想到半個(gè)月后佣渴,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡初斑,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年辛润,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片见秤。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡砂竖,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出鹃答,到底是詐尸還是另有隱情乎澄,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布测摔,位于F島的核電站置济,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏锋八。R本人自食惡果不足惜浙于,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望查库。 院中可真熱鬧路媚,春花似錦、人聲如沸樊销。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)围苫。三九已至裤园,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間剂府,已是汗流浹背拧揽。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留腺占,地道東北人淤袜。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像衰伯,于是被迫代替她去往敵國(guó)和親铡羡。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 概述 虛擬機(jī)把描述類的數(shù)據(jù)從Class文件加載到內(nèi)存中意鲸,并對(duì)數(shù)據(jù)進(jìn)行驗(yàn)證烦周,準(zhǔn)備尽爆,解析,初始化的一個(gè)過(guò)程读慎,最終是可以...
    Wen_Q_M閱讀 281評(píng)論 0 1
  • 一漱贱、類加載機(jī)制 1.定義: 把描述類的數(shù)據(jù)從Class文件加載到內(nèi)存,并對(duì)數(shù)據(jù)進(jìn)行校驗(yàn)夭委、轉(zhuǎn)換解析和初始化幅狮,最終形成...
    Ruheng閱讀 2,334評(píng)論 6 36
  • 基于JVM的語(yǔ)言,如java,kotlin,groovy等語(yǔ)言闰靴,在各自編譯器編譯完成之后彪笼,都會(huì)編譯為.class文...
    Vinctor閱讀 1,067評(píng)論 2 5
  • Java的核心是 JVM 钻注,了解并熟悉JVM對(duì)于我們理解Java語(yǔ)言非常重要蚂且。 一、類加載機(jī)制 當(dāng)程序主動(dòng)使用某個(gè)...
    年少懵懂丶流年夢(mèng)閱讀 1,088評(píng)論 2 15
  • 什么是虛擬機(jī)的類加載機(jī)制幅恋?虛擬機(jī)把描述類的數(shù)據(jù)從Class文件加載到內(nèi)存杏死,并對(duì)數(shù)據(jù)進(jìn)行校驗(yàn)、轉(zhuǎn)換解析以及初始化捆交,最...
    EakonZhao閱讀 2,336評(píng)論 6 22