Java 虛擬機(jī)、Art啊片、Dalvik 他們的區(qū)別

1.JVM與DVM

1.概念

JVM的作用是把平臺(tái)無(wú)關(guān)的.class里面的字節(jié)碼翻譯成平臺(tái)相關(guān)的機(jī)器碼只锻,來(lái)實(shí)現(xiàn)跨平臺(tái)。DVM就是安卓中使用的虛擬機(jī)钠龙。

Dalvik允許多個(gè)實(shí)例炬藤,每一個(gè)實(shí)例作為一個(gè)獨(dú)立的linux進(jìn)程執(zhí)行御铃,可以防止一個(gè)程序的崩潰導(dǎo)致所有程序都崩潰。

2.區(qū)別
  • jvm通過(guò)解碼class文件來(lái)運(yùn)行程序沈矿;dvm則是dex文件上真。

dex文件是由多個(gè)class文件打包而成,一個(gè)dex文件方法數(shù)不能超過(guò)65535羹膳。

 JVM: .java -> javac -> .class -> jar -> .jar , 架構(gòu): 堆和棧的架構(gòu).
 DVM: .java -> javac -> .class -> dx.bat -> .dex , 架構(gòu): 寄存器(cpu上的一塊高速緩存)睡互。

Dalvik字節(jié)碼中,變量會(huì)被復(fù)制給65536個(gè)可用寄存器中的任何一個(gè)陵像,直接訪問(wèn)這些寄存器就珠,而不是方位堆棧中的元素;
JVM字節(jié)碼中醒颖,變量會(huì)被壓入堆棧中進(jìn)行運(yùn)算妻怎;基于寄存器的方式在編譯的時(shí)候花費(fèi)的時(shí)間更短。這也是下面要說(shuō)的泞歉。

  • dvm基于寄存器架構(gòu)(句柄引用)逼侦,jvm基于棧架構(gòu)(指針引用)

dvm基于寄存器,所以它的指令是二地址和三地址混合腰耙,指令中指明了操作數(shù)的地址榛丢;jvm基于棧,它的指令是零地址挺庞,指令的操作數(shù)對(duì)象默認(rèn)是操作數(shù)棧中的幾個(gè)位置晰赞。但基于寄存器的指令由于需要指定源地址和目標(biāo)地址,因此需要占用更多的指令空間

dvm速度快选侨!指令數(shù)小掖鱼!寄存器存取速度比棧快的多侵俗,dvm可以根據(jù)硬件實(shí)現(xiàn)最大的優(yōu)化锨用,比較適合移動(dòng)設(shè)備丰刊。JAVA虛擬機(jī)基于棧結(jié)構(gòu)隘谣,程序在運(yùn)行時(shí)虛擬機(jī)需要頻繁的從棧上讀取寫(xiě)入數(shù)據(jù),這個(gè)過(guò)程需要更多的指令分派與內(nèi)存訪問(wèn)次數(shù)啄巧,會(huì)耗費(fèi)很多CPU時(shí)間寻歧。

這樣帶來(lái)的結(jié)果就是dvm的指令數(shù)相對(duì)于jvm的指令數(shù)會(huì)小很多,jvm需要多條指令而dvm可能只需要一條指令秩仆。jvm基于棧帶來(lái)的好處是可以做的足夠簡(jiǎn)單码泛,真正的跨平臺(tái),保證在低硬件條件下能夠正常運(yùn)行澄耍。而dvm操作平臺(tái)一般指明是ARM系統(tǒng)噪珊,所以采取的策略有所不同晌缘。需要注意的是dvm基于寄存器,但是這也是個(gè)映射關(guān)系痢站,如果硬件沒(méi)有足夠的寄存器磷箕,dvm將多出來(lái)的寄存器映射到內(nèi)存中

  • Dalvik可執(zhí)行文件體積更小阵难。

SDK中有個(gè)dx工具負(fù)責(zé)將JAVA字節(jié)碼轉(zhuǎn)換為Dalvik字節(jié)碼岳枷,將所有java文件中的常量池合并為一個(gè)常量池,使得相同的字符串和常量只在DEX文件中出現(xiàn)一次呜叫。

運(yùn)行時(shí)空繁,共享相同的類(lèi),這樣系統(tǒng)消耗會(huì)小很多朱庆,JVM機(jī)制中盛泡,打包后,他們都是完全獨(dú)立的程序娱颊,類(lèi)都是單獨(dú)加載饭于,單獨(dú)運(yùn)行;

3.jvm(參考)

當(dāng)啟動(dòng)一個(gè)java程序维蒙,一個(gè)虛擬機(jī)實(shí)例也就誕生了掰吕。當(dāng)該程序關(guān)閉退出,這個(gè)虛擬機(jī)實(shí)例也就隨之消亡颅痊。

java內(nèi)部有兩種線(xiàn)程:守護(hù)線(xiàn)程和非守護(hù)線(xiàn)程殖熟。非守護(hù)線(xiàn)程就是我們所說(shuō)的main方法;守護(hù)線(xiàn)程通常是由虛擬機(jī)自己使用斑响,如執(zhí)行垃圾回收任務(wù)的線(xiàn)程菱属。Java程序也可以把它創(chuàng)建的任何線(xiàn)程標(biāo)記為守護(hù)線(xiàn)程。只要還有非守護(hù)進(jìn)行在舰罚,這個(gè)java程序也在繼續(xù)進(jìn)行纽门。

虛擬機(jī)的結(jié)構(gòu)圖

每個(gè)Java虛擬機(jī)都有一個(gè)類(lèi)裝載子系統(tǒng),它根據(jù)給定的全限定名來(lái)裝入類(lèi)型(類(lèi)或接口)营罢。同樣赏陵,每個(gè)Java虛擬機(jī)都有一個(gè)執(zhí)行引擎,它負(fù)責(zé)執(zhí)行那些包含在被裝載類(lèi)的方法中的指令饲漾。

每個(gè)Java虛擬機(jī)實(shí)例都有一個(gè)方法區(qū)以及一個(gè)堆蝙搔,它們是由該虛擬機(jī)實(shí)例中所有的線(xiàn)程共享的。當(dāng)虛擬機(jī)裝載一個(gè)class文件時(shí)考传,它會(huì)從這個(gè)class文件包含的二進(jìn)制數(shù)據(jù)中解析類(lèi)型信息吃型。然后把這些類(lèi)型信息放到方法區(qū)中。當(dāng)程序運(yùn)行時(shí)僚楞,虛擬機(jī)會(huì)把所有該程序在運(yùn)行時(shí)創(chuàng)建的對(duì)象都放到堆中勤晚。

當(dāng)每一個(gè)新線(xiàn)程被創(chuàng)建時(shí)枉层,它都將得到它自己的PC寄存器(程序計(jì)數(shù)器)以及一個(gè)Java棧。如果線(xiàn)程正在執(zhí)行的是一個(gè)Java方法(非本地方法)赐写,那么PC寄存器的值將總是指向下一條將被執(zhí)行的指令返干,java棧存儲(chǔ)該線(xiàn)程中Java方法調(diào)用的狀態(tài)——包括它的局部變量,被調(diào)用時(shí)傳進(jìn)來(lái)的參數(shù)血淌、返回值矩欠,以及運(yùn)算的中間結(jié)果等等。而本地方法調(diào)用的狀態(tài)悠夯,則是以某種依賴(lài)于具體實(shí)現(xiàn)的方法存儲(chǔ)在本地方法棧中癌淮,也可能是在寄存器或者其他某些與特定實(shí)現(xiàn)相關(guān)的內(nèi)存區(qū)中。

Java虛擬機(jī)沒(méi)有寄存器沦补,其指令集使用Java棧來(lái)存儲(chǔ)中間數(shù)據(jù)乳蓄。Java棧是由許多棧幀(stack frame)組成的,一個(gè)棧幀包含一個(gè)Java方法調(diào)用的狀態(tài)夕膀。當(dāng)線(xiàn)程調(diào)用一個(gè)Java方法時(shí)虚倒,虛擬機(jī)壓入一個(gè)新的棧幀到該線(xiàn)程的Java棧中,當(dāng)該方法返回時(shí)产舞,這個(gè)棧幀被從Java棧中彈出并拋棄魂奥。

虛擬機(jī)必須為每個(gè)被裝載的類(lèi)型維護(hù)一個(gè)常量池。常量池就是該類(lèi)型所用常量的一個(gè)有序集合易猫,包括直接常量和對(duì)其他類(lèi)型耻煤、字段和方法的符號(hào)引用。池中的數(shù)據(jù)項(xiàng)就像數(shù)組一樣是通過(guò)索引訪問(wèn)的准颓。因?yàn)槌A砍卮鎯?chǔ)了相應(yīng)類(lèi)型所用到的所有類(lèi)型哈蝇、字段和方法的符號(hào)引用,所以它在Java程序的動(dòng)態(tài)連接中起著核心的作用攘已。
創(chuàng)建對(duì)象就是通過(guò)常量池中對(duì)應(yīng)類(lèi)的引用找到方法區(qū)中對(duì)應(yīng)類(lèi)炮赦。

4.Dalvik

Dalvik將堆分成了Active堆和Zygote堆,Zygote堆是Zygote進(jìn)程在啟動(dòng)的時(shí)候預(yù)加載的類(lèi)样勃、資源和對(duì)象吠勘,除此之外的所有對(duì)象都是存儲(chǔ)在Active堆中的。

Dalvik的gygote堆存放的預(yù)加載的類(lèi)都是Android核心類(lèi)和java運(yùn)行時(shí)庫(kù)彤灶,這部分內(nèi)容很少被修改看幼,大多數(shù)情況父進(jìn)程和子進(jìn)程共享這塊內(nèi)存區(qū)域批旺。通常垃圾回收重點(diǎn)對(duì)Active堆進(jìn)行回收操作幌陕,Dalvik為了對(duì)堆進(jìn)行更好的管理創(chuàng)建了一個(gè)Card Table、兩個(gè)Heap Bitmap和一個(gè)Mark Stack數(shù)據(jù)結(jié)構(gòu)汽煮。

許多GC實(shí)現(xiàn)都是在對(duì)象開(kāi)頭的地方留一小塊空間給GC標(biāo)記用搏熄。Dalvik VM則不同棚唆,在進(jìn)行GC的時(shí)候會(huì)單獨(dú)申請(qǐng)一塊空間,以位圖的形式來(lái)保存整個(gè)堆上的對(duì)象的標(biāo)記心例,在GC結(jié)束后就釋放該空間宵凌。

Dalvik使用即時(shí)編譯(JIT),即是在程序運(yùn)行過(guò)程中進(jìn)行編譯止后。JIT會(huì)在運(yùn)行時(shí)分析應(yīng)用程序的代碼瞎惫,識(shí)別哪些方法可以歸類(lèi)為熱方法,這些方法會(huì)被JIT編譯器編譯成對(duì)應(yīng)的匯編代碼译株,然后存儲(chǔ)到代碼緩存中瓜喇,以后調(diào)用這些方法時(shí)就不用解釋執(zhí)行了,可以直接使用代碼緩存中已編譯好的匯編代碼歉糜。

javac把程序源碼編譯成JAVA字節(jié)碼乘寒,JVM通過(guò)逐條解釋字節(jié)碼將其翻譯成對(duì)應(yīng)的機(jī)器指令,逐條讀入匪补,逐條解釋翻譯伞辛,執(zhí)行速度必然比C/C++編譯后的可執(zhí)行二進(jìn)制字節(jié)碼程序慢,為了提高執(zhí)行速度夯缺,就引入了JIT技術(shù)蚤氏。

2.ART

與Dalvik不同,ART使用預(yù)編譯(AOT,Ahead-Of-Time)踊兜。也就是在APK運(yùn)行之前瞧捌,就對(duì)其包含的Dex字節(jié)碼進(jìn)行翻譯,得到對(duì)應(yīng)的本地機(jī)器指令润文,于是就可以在運(yùn)行時(shí)直接執(zhí)行了姐呐。

ART應(yīng)用安裝的時(shí)候把dex中的字節(jié)碼將被編譯成本地機(jī)器碼,之后每次打開(kāi)應(yīng)用典蝌,執(zhí)行的都是本地機(jī)器碼曙砂。去除了運(yùn)行時(shí)的解釋執(zhí)行,效率更高骏掀,啟動(dòng)更快鸠澈。

在Android系統(tǒng)啟動(dòng)過(guò)程中創(chuàng)建的Zygote進(jìn)程利用ART運(yùn)行時(shí)導(dǎo)出的Java虛擬機(jī)接口創(chuàng)建ART虛擬機(jī)。APK在安裝的時(shí)候截驮,打包在里面的classes.dex文件會(huì)被工具dex2oat翻譯成本地機(jī)器指令笑陈,最終得到一個(gè)ELF格式的oat文件。APK運(yùn)行時(shí)葵袭,上述生成的oat文件會(huì)被加載到內(nèi)存中涵妥,并且ART虛擬機(jī)可以通過(guò)里面的oatdataoatexec段找到任意一個(gè)類(lèi)的方法對(duì)應(yīng)的本地機(jī)器指令來(lái)執(zhí)行。 oat文件中的oatdata包含用來(lái)生成本地機(jī)器指令的dex文件坡锡,內(nèi)容oat文件中的oatexec包含有生成的本地機(jī)器指令蓬网。

可以分配內(nèi)存的Space有三個(gè):Zygote Space窒所、Allocation Space和Large Object Space。實(shí)際上應(yīng)用運(yùn)行的時(shí)候能夠分配內(nèi)存也就Allocation 和 Large Object Space兩個(gè)帆锋。

image

ART優(yōu)點(diǎn):
①系統(tǒng)性能顯著提升吵取,每次啟動(dòng)執(zhí)行的時(shí)候,都可以直接運(yùn)行锯厢,因此運(yùn)行效率會(huì)提高皮官。
②應(yīng)用啟動(dòng)更快、運(yùn)行更快实辑、體驗(yàn)更流暢臣疑、觸感反饋更及時(shí)
③續(xù)航能力提升,因?yàn)閼?yīng)用程序每次運(yùn)行時(shí)不用重復(fù)編譯了徙菠,從而減少了 CPU 的使用頻率讯沈,降低了能耗。
④支持更低的硬件

ART缺點(diǎn)
①更大的存儲(chǔ)空間占用婿奔,可能增加10%-20%(字節(jié)碼變?yōu)闄C(jī)器碼之后缺狠,可能會(huì)增加10%-20%)
②更長(zhǎng)的應(yīng)用安裝時(shí)間,應(yīng)用在第一次安裝的時(shí)候萍摊,字節(jié)碼就會(huì)預(yù)編譯(AOT)成機(jī)器碼挤茄,這樣的話(huà),雖然設(shè)備和應(yīng)用的首次啟動(dòng)(安裝慢了)會(huì)變慢

4.android7.0\7.1

android7.0\7.1的ART引入了全新的Hybrid模式(Interpreter + JIT + AOT)

  • 與前面不同冰木,app在安裝時(shí)不進(jìn)行編譯穷劈,所以安裝速度會(huì)更快。
  • 在運(yùn)行App時(shí)踊沸, 先走解釋器歇终, 然后熱點(diǎn)函數(shù)會(huì)被識(shí)別,并被JIT進(jìn)行編譯逼龟, 存儲(chǔ)在jit code cache评凝, 并產(chǎn)生profile文件(記錄熱點(diǎn)函數(shù)信息)。
  • 等手機(jī)進(jìn)入充電和空閑狀態(tài)下腺律, 系統(tǒng)會(huì)每隔一段時(shí)間掃描App目錄下profile文件奕短,并執(zhí)行AOT編譯(Google官方稱(chēng)之為profile-guided compilation)。
  • 不論是jit編譯的binary code, 還是AOT編譯的binary code, 它們之間的性能差別不大匀钧, 因?yàn)樗鼈兪褂猛粋€(gè)optimizing compiler進(jìn)行編譯翎碑。

這樣的優(yōu)點(diǎn)是:App安裝速度快,占用存儲(chǔ)少(只編譯熱點(diǎn)函數(shù))之斯。

缺點(diǎn)是:前幾次運(yùn)行會(huì)較慢日杈, 只有用戶(hù)操作得次數(shù)越多,jit 和AOT編譯后, 性能才會(huì)跟上來(lái)达椰。

后記

垃圾回收機(jī)制也是很重要的一環(huán)翰蠢,但這個(gè)能說(shuō)的太多了项乒。
參考:

JVM啰劲、Dalvik VM和ART虛擬機(jī)之間的區(qū)別

Dalvik虛擬機(jī)簡(jiǎn)要介紹和學(xué)習(xí)計(jì)劃

JAVA虛擬機(jī)、Dalvik虛擬機(jī)和ART虛擬機(jī)簡(jiǎn)要對(duì)比

JAVA虛擬機(jī)的生命周期

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末檀何,一起剝皮案震驚了整個(gè)濱河市蝇裤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌频鉴,老刑警劉巖栓辜,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異垛孔,居然都是意外死亡藕甩,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén)周荐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)狭莱,“玉大人,你說(shuō)我怎么就攤上這事概作∫该睿” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵讯榕,是天一觀的道長(zhǎng)骤素。 經(jīng)常有香客問(wèn)我,道長(zhǎng)愚屁,這世上最難降的妖魔是什么济竹? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮霎槐,結(jié)果婚禮上规辱,老公的妹妹穿的比我還像新娘。我一直安慰自己栽燕,他們只是感情好罕袋,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著碍岔,像睡著了一般浴讯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蔼啦,一...
    開(kāi)封第一講書(shū)人閱讀 51,292評(píng)論 1 301
  • 那天榆纽,我揣著相機(jī)與錄音,去河邊找鬼。 笑死奈籽,一個(gè)胖子當(dāng)著我的面吹牛饥侵,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播衣屏,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼躏升,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了狼忱?” 一聲冷哼從身側(cè)響起膨疏,我...
    開(kāi)封第一講書(shū)人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎钻弄,沒(méi)想到半個(gè)月后佃却,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡窘俺,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年饲帅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瘤泪。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡灶泵,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出均芽,到底是詐尸還是另有隱情丘逸,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布掀宋,位于F島的核電站深纲,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏劲妙。R本人自食惡果不足惜湃鹊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望镣奋。 院中可真熱鬧币呵,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至妻柒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間耘分,已是汗流浹背举塔。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工绑警, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人央渣。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓计盒,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親芽丹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子北启,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

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