classloader

前言

最近看了很多關(guān)于classloader的文章洞渤,想了解一下classload具體的工作原理。因?yàn)榍皫兹崭栌蚜奶炖常f(shuō)讓我研究研究Android的插件技術(shù)住闯。隨后我搜索一些相關(guān)的資料,其中有一篇博文講到其底層的技術(shù)就是ClassLoader拂酣,所以要對(duì)java的ClassLoader有一定的了解秋冰。當(dāng)然,隨著最近幾天的閱讀婶熬,也對(duì)插件技術(shù)有了一定程度的認(rèn)知剑勾。各種框架,各種技術(shù)流派在國(guó)內(nèi)可謂層出不窮赵颅,阿里的ATLAS虽另,攜程的DynamicAPK,奇虎360的DriodPlugin等等饺谬。但似乎很少看到國(guó)外對(duì)此技術(shù)的熱衷捂刺,雖然Google給了一個(gè)MultiDex,但谷歌還是不建議這么做募寨,尤其隨著ReactNative的興起族展,通過(guò)JsPath即可實(shí)現(xiàn)熱修復(fù)(iOS),相必其可能是未來(lái)的發(fā)展方向拔鹰。當(dāng)然仪缸,通過(guò)對(duì)Android插件技術(shù)的學(xué)習(xí),也是一個(gè)對(duì)Android四大組件(Activity列肢,Service腹殿,Broadcast,Content Provider)充分認(rèn)識(shí)的過(guò)程例书,畢竟背后隱藏的邏輯也逃不過(guò)這些基礎(chǔ)的東西锣尉。基礎(chǔ)中的基礎(chǔ)那么可能就是ClassLoader了吧决采。

關(guān)于ClassLoader

ClassLoader從名字就能看出自沧,類加載器。為什么要類加載器树瞭?這使我想起了.NET的程序集的概念拇厢,很像。一個(gè)Assembly.Load就能將一個(gè)DLL加載進(jìn)來(lái)晒喷。很遺憾孝偎,沒有對(duì).NET程序集更深層次做挖掘,所以希望能對(duì)java的類加載機(jī)制有一定認(rèn)識(shí)凉敲。我們知道引入一個(gè)類衣盾,只需要import java.io.File寺旺,沒錯(cuò)import,為什么使用這個(gè)關(guān)鍵字就能加載势决?對(duì)于java的基礎(chǔ)類庫(kù)來(lái)說(shuō)阻塑,虛擬機(jī)幫你做好了。這個(gè)就跟.NET一樣果复,一個(gè)using就可以加載全局程序集陈莽,而要加載自定義的程序集,就必須在相同目錄虽抄,即私有程序集走搁。JAVA也一樣,有安裝java的時(shí)候自帶的迈窟,也有你自己定義的私植,你可以把你的jar放在lib目錄,也可以放在當(dāng)前目錄菠隆,隨你兵琳。

編譯的過(guò)程

JAVA屬于解釋型的編程語(yǔ)言狂秘,這個(gè)不用多解釋吧骇径,就是不編譯成最終的目標(biāo)平臺(tái)的二進(jìn)制,而是編譯成中間語(yǔ)言者春,.NET叫IL破衔,JAVA叫.class,叫啥無(wú)所謂钱烟,都一樣晰筛。傳統(tǒng)的編譯過(guò)程是編譯成目標(biāo)文件,然后在對(duì)目標(biāo)文件進(jìn)行鏈接拴袭,但是對(duì)于JAVA而言读第,首先編譯成的是字節(jié)碼.class文件,在JVM加載class的時(shí)候拥刻,才進(jìn)行鏈接怜瞒。整個(gè)java的執(zhí)行過(guò)程,按照J(rèn)ava Language Specification第12章的介紹般哼,分為如下幾個(gè)過(guò)程:

  1. JVM運(yùn)行吴汪。
  2. 加載Main函數(shù)(啟動(dòng)類)
  3. 對(duì)目標(biāo)類進(jìn)行鏈接(驗(yàn)證,準(zhǔn)備蒸眠,保留)
  4. 初始化漾橙。
  5. 創(chuàng)建。
  6. 終結(jié)一個(gè)類
  7. 卸載楞卡。
  8. 程序退出霜运。

三個(gè)類

Paste_Image.png
  • BootstrapClassLoader: 這個(gè)是native code寫的脾歇,嵌入在jvm里,虛擬機(jī)啟動(dòng)的時(shí)候自動(dòng)啟動(dòng)bootstrapclassloader觉渴,加載lib下的類庫(kù)介劫。
  • ExtensionClassLoader: 負(fù)責(zé)加載lib/ext里面的類庫(kù)。
  • ApplicationClassLoader: 負(fù)責(zé)加載CLASSPATH里面的類庫(kù)案淋。
  • 三者的關(guān)系是:看上圖座韵,下面的繼承上面的類。上面的為下面的parent踢京。
  • 加載的順序:先是BootstrapClassLoader加載誉碴,如果它沒有找到,則ExtensionClassLoader嘗試加載瓣距,如果它也沒找到黔帕,則ApplicationClassLoader進(jìn)行加載,都沒找到蹈丸,ClassNotFoundException成黄。
  • 加載原理:雙親委托法,即child依次委托parent進(jìn)行查找逻杖。(各博文均介紹如此)
  • ClassLoader使用loadClass方法加載一個(gè)類:
    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;
        }
    }

查看繼承關(guān)系

public class LucasMainEntry {
    public static void main(String[] args) {
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        while(loader != null) {
            System.out.println(loader);
           loader = loader.getParent();
        }
    }
}
sun.misc.Launcher$AppClassLoader@2a139a55
sun.misc.Launcher$ExtClassLoader@7852e922
null

我們可以看到對(duì)應(yīng)的父子關(guān)系奋岁。

加載過(guò)程中的問(wèn)題

一個(gè)類如果被兩個(gè)不同的loader加載,那么即便他們有相同的命名空間以及名稱荸百,JVM仍然認(rèn)為他們不是同一個(gè)類闻伶。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市够话,隨后出現(xiàn)的幾起案子蓝翰,更是在濱河造成了極大的恐慌,老刑警劉巖女嘲,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件畜份,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡欣尼,警方通過(guò)查閱死者的電腦和手機(jī)爆雹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)媒至,“玉大人顶别,你說(shuō)我怎么就攤上這事【軉” “怎么了驯绎?”我有些...
    開封第一講書人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)谋旦。 經(jīng)常有香客問(wèn)我剩失,道長(zhǎng)屈尼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任拴孤,我火速辦了婚禮脾歧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘演熟。我一直安慰自己鞭执,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開白布芒粹。 她就那樣靜靜地躺著兄纺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪化漆。 梳的紋絲不亂的頭發(fā)上估脆,一...
    開封第一講書人閱讀 49,046評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音座云,去河邊找鬼疙赠。 笑死,一個(gè)胖子當(dāng)著我的面吹牛朦拖,可吹牛的內(nèi)容都是我干的圃阳。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼贞谓,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼限佩!你這毒婦竟也來(lái)了葵诈?” 一聲冷哼從身側(cè)響起裸弦,我...
    開封第一講書人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎作喘,沒想到半個(gè)月后理疙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡泞坦,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年窖贤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贰锁。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡赃梧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出豌熄,到底是詐尸還是另有隱情授嘀,我是刑警寧澤,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布锣险,位于F島的核電站蹄皱,受9級(jí)特大地震影響览闰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜巷折,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一压鉴、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧锻拘,春花似錦油吭、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至芯丧,卻和暖如春芍阎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背缨恒。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工谴咸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人骗露。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓岭佳,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親萧锉。 傳聞我的和親對(duì)象是個(gè)殘疾皇子珊随,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

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

  • 安卓插件化越來(lái)越流行,其中用到的技術(shù)不外乎加載外部的資源和加載外部的代碼,關(guān)于加載外部資源我之前寫過(guò)一篇文章《安卓...
    嘉偉咯閱讀 1,602評(píng)論 5 14
  • 作者簡(jiǎn)介 原創(chuàng)微信公眾號(hào)郭霖 WeChat ID: guolin_blog 本篇是fank909的第四篇投稿叶洞,詳細(xì)...
    木木00閱讀 1,598評(píng)論 1 14
  • 好久不寫日志了。還記得以前有個(gè)姑娘說(shuō)禀崖,看我的日志感覺很好衩辟。只是,你們都不會(huì)再看到波附。即使某些人還在艺晴。 有說(shuō)過(guò),人一直...
    趙業(yè)閱讀 191評(píng)論 0 1
  • 畫著好玩的畫掸屡,繼續(xù)小姐姐
    夏秋愛畫閱讀 234評(píng)論 0 0
  • 聽梵音和我們平時(shí)去看演唱會(huì)一點(diǎn)都不一樣封寞。一個(gè)熱鬧狂熱,一個(gè)安和寧?kù)o仅财。 現(xiàn)場(chǎng)聽梵音和自己在手機(jī)聽也不一樣狈究,現(xiàn)場(chǎng)版更空...
    真墨流歌閱讀 157評(píng)論 0 0