Android虛擬機(jī)與類加載機(jī)制

JVM和Dalvik/ART

Android應(yīng)用程序運(yùn)行在Dalvik/ART虛擬機(jī),并且每一個應(yīng)用程序?qū)?yīng)有一個單獨(dú)的Dalvik虛擬機(jī)實(shí)例棕诵。Dalvik虛擬機(jī)實(shí)則也算是一個Java虛擬機(jī)裁良,只不過它執(zhí)行的不是class文件,而是dex文件校套。Dalvik虛擬機(jī)與Java虛擬機(jī)共享有差不多的特性价脾,差別在于兩者執(zhí)行的指令集是不一樣的,前者的指令集是基本寄存器的笛匙,而后者的指令集是基于堆棧的侨把。

基于棧的虛擬機(jī)

對于基于棧的虛擬機(jī)來說,每一個運(yùn)行時的線程妹孙,都有一個獨(dú)立的棧秋柄。棧中記錄了方法調(diào)用的歷史,每有一次方法調(diào)用蠢正,棧中便會多一個棧楨骇笔。最頂部的棧楨稱作當(dāng)前棧楨,其代表著當(dāng)前執(zhí)行的方法嚣崭”看ィ基于棧的虛擬機(jī)通過操作數(shù)棧進(jìn)行所有操作。

public class Demo {
    public static void test() {
        int a = 1;
        int b = 2;
        int c = a + b;
    }
}

使用javap -c xxx.class進(jìn)行反編譯雹舀,查看字節(jié)碼指令:

  • iconst_1:將int類型常量a壓入操作數(shù)棧
  • istore_0:將int類型常量a存入局部變量0
  • iadd:執(zhí)行int類型的加法操作

執(zhí)行過程如下:

基于寄存器的虛擬機(jī)

寄存器是CPU的組成部分芦劣。寄存器是有限存貯容量的高速存貯部件,它們可用來暫存指令说榆、數(shù)據(jù)和位址虚吟。

基于寄存器的虛擬機(jī)中沒有操作數(shù)棧系吩,但是有很多虛擬寄存器坚弱。其實(shí)和操作數(shù)棧相同,這些寄存器也存放在運(yùn)行時棧中灶似,本質(zhì)上就是一個數(shù)組荠卷。與JVM相似模庐,在Dalvik VM中每個線程都有自己的PC和調(diào)用棧,方法調(diào)用的活動記錄以幀為單位保存在調(diào)用棧上油宜。

與JVM版相比掂碱,可以發(fā)現(xiàn)Dalvik版程序的指令數(shù)明顯減少了,數(shù)據(jù)移動次數(shù)也明顯減少了慎冤。

ART和Dalvik

Dalvik虛擬機(jī)執(zhí)行的是dex字節(jié)碼疼燥,解釋執(zhí)行。 從Android 2.2版本開始蚁堤,支持JIT即時編譯(Just In Time)在程序運(yùn)行的過程中進(jìn)行選擇熱點(diǎn)代碼(經(jīng)常執(zhí)行的代碼)進(jìn)行編譯或者優(yōu)化醉者。而ART(Android Runtime) 是在 Android 4.4 中引入的一個開發(fā)者選項,也是 Android 5.0 及更高版本的默認(rèn) Android 運(yùn)行時。ART虛擬機(jī)執(zhí)行的是本地機(jī)器碼撬即。 Android的運(yùn)行時從Dalvik虛擬機(jī)替換成ART虛擬機(jī)立磁,并不要求開發(fā)者將自己的應(yīng)用直接編譯成目標(biāo)機(jī)器碼,APK仍然是一個包含dex字節(jié)碼的文件剥槐。

dex2aot

Dalvik下應(yīng)用在安裝的過程唱歧,會執(zhí)行一次優(yōu)化,將dex字節(jié)碼進(jìn)行優(yōu)化生成odex文件粒竖。而Art下將應(yīng)用的dex字節(jié)碼翻譯成本地機(jī)器碼的最恰當(dāng)AOT時機(jī)也就發(fā)生在應(yīng)用安裝的時候颅崩。ART 引入了預(yù)先編譯機(jī)制**(Ahead Of Time),在安裝時蕊苗,ART 使用設(shè)備自帶的 dex2oat 工具來編譯應(yīng)用沿后,dex中的字節(jié)碼將被編譯成本地機(jī)器碼。

Android N(7.0)的運(yùn)作方式

ART 使用預(yù)先 (AOT) 編譯朽砰,并且從 Android N混合使用AOT編譯得运,解釋和JIT。

1锅移、最初安裝應(yīng)用時不進(jìn)行任何 AOT 編譯(安裝又快了),運(yùn)行過程中解釋執(zhí)行饱搏,對經(jīng)常執(zhí)行的方法進(jìn)行JIT非剃,經(jīng)過 JIT 編譯的方法將會記錄到Profile配置文件中。

2推沸、當(dāng)設(shè)備閑置和充電時备绽,編譯守護(hù)進(jìn)程會運(yùn)行,根據(jù)Profile文件對常用代碼進(jìn)行 AOT 編譯鬓催。待下次運(yùn)行時直接使用肺素。

類加載機(jī)制

雙親委派機(jī)制

protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
            //檢查類是否已經(jīng)被加載過
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                //沒被加載過,就去加載該類
                try {
                    if (parent != null) {
                        //parent不為null宇驾,則調(diào)用parent的loadClass去加載
                        c = parent.loadClass(name, false);
                    } else {
                        //parent為null倍靡,則調(diào)用BootClassLoader去加載類(從Framework中找)
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // ClassNotFoundException thrown if class not found
                    // from the non-null parent class loader
                }

                if (c == null) {
                    //如果還是找不到,就調(diào)用findClass自己去找(從app中找)
                    c = findClass(name);
                }
            }
            return c;
    }

某個類加載器在加載類時课舍,首先將加載任務(wù)委托給父類加載器塌西,依次遞歸,如果父類加載器可以完成類加載任務(wù)筝尾,就成功返回捡需;只有父類加載器無法完成此加載任務(wù)或者沒有父類加載器時,才自己去加載筹淫。

好處:

1站辉、避免重復(fù)加載,當(dāng)父加載器已經(jīng)加載了該類的時候,就沒有必要子ClassLoader再加載一次饰剥。

2殊霞、安全性考慮,防止核心API庫被隨意篡改捐川。

類加載過程

關(guān)注木水小站 (zhangmushui.cn)和微信公眾號【木水Code】脓鹃,及時獲取更多最新技術(shù)干貨。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末古沥,一起剝皮案震驚了整個濱河市瘸右,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌岩齿,老刑警劉巖太颤,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異盹沈,居然都是意外死亡龄章,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門乞封,熙熙樓的掌柜王于貴愁眉苦臉地迎上來做裙,“玉大人,你說我怎么就攤上這事肃晚∶” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵关串,是天一觀的道長拧廊。 經(jīng)常有香客問我,道長晋修,這世上最難降的妖魔是什么吧碾? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮墓卦,結(jié)果婚禮上倦春,老公的妹妹穿的比我還像新娘。我一直安慰自己趴拧,他們只是感情好溅漾,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著著榴,像睡著了一般添履。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上脑又,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天暮胧,我揣著相機(jī)與錄音锐借,去河邊找鬼。 笑死往衷,一個胖子當(dāng)著我的面吹牛钞翔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播席舍,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼布轿,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了来颤?” 一聲冷哼從身側(cè)響起汰扭,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎福铅,沒想到半個月后萝毛,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡滑黔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年笆包,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片略荡。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡庵佣,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出汛兜,到底是詐尸還是另有隱情秧了,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布序无,位于F島的核電站,受9級特大地震影響衡创,放射性物質(zhì)發(fā)生泄漏帝嗡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一璃氢、第九天 我趴在偏房一處隱蔽的房頂上張望哟玷。 院中可真熱鬧,春花似錦一也、人聲如沸巢寡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽抑月。三九已至,卻和暖如春舆蝴,著一層夾襖步出監(jiān)牢的瞬間谦絮,已是汗流浹背题诵。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留层皱,地道東北人性锭。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像叫胖,于是被迫代替她去往敵國和親草冈。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

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