安卓目前有兩種虛擬機(jī)顽照,Dalvik跟Art,Art是M之后才出的闽寡,Dalvik是Google公司自己設(shè)計(jì)用于Android平臺(tái)的Java虛擬機(jī)代兵,它是Android平臺(tái)的重要組成部分,支持dex格式(Dalvik Executable)的Java應(yīng)用程序的運(yùn)行爷狈。dex格 式是專門為Dalvik設(shè)計(jì)的一種壓縮格式植影,適合內(nèi)存和處理器速度有限的系統(tǒng)。
從 Android系統(tǒng)架構(gòu)圖知涎永,Dalvik虛擬機(jī)運(yùn)行在Android的運(yùn)行時(shí)庫(kù)層(上層是運(yùn)行時(shí)核心庫(kù))思币。
主要負(fù)責(zé)完成對(duì)象生命周期管理鹿响、堆棧管理、線程管理谷饿、安全和異常管理惶我,以及垃圾回收等。當(dāng)然這些大家都知道博投,下面來(lái)看看幾個(gè)區(qū)別绸贡。
Dalvik跟 JVM區(qū)別
運(yùn)行內(nèi)容
dvm運(yùn)行的是dalvik字節(jié)碼,jvm運(yùn)行java字節(jié)碼毅哗。
Java程序經(jīng)過編譯听怕,生成Java字節(jié)碼保存在class文件中,Java虛擬機(jī)通過解碼class文件中的內(nèi)容來(lái)運(yùn)行程序虑绵。而Dalvik虛擬機(jī)運(yùn)行的是Dalvik字節(jié)碼叉跛,所有的Dalvik字節(jié)碼由Java字節(jié)碼轉(zhuǎn)換而來(lái),并被打包到一個(gè)DEX可執(zhí)行文件中蒸殿。Dalvik虛擬機(jī)通過解釋DEX文件來(lái)執(zhí)行這些字節(jié)碼。
也就是說(shuō)鸣峭,在生成字節(jié)碼之后宏所,兩個(gè)虛擬機(jī)就各自有自己的想法了,jvm直接對(duì)class文件操作了摊溶,dvm其實(shí)簡(jiǎn)單來(lái)看也差不多爬骤,經(jīng)過DX工具將class文件轉(zhuǎn)換成Dalvik虛擬機(jī)可以執(zhí)行的dex文件,生成的是dalvik字節(jié)碼莫换。
類結(jié)構(gòu)
dx工具對(duì)Java類文件重新排列霞玄,消除在類文件中出現(xiàn)的所有冗余信息,避免虛擬機(jī) 在初始化時(shí)出現(xiàn)反復(fù)的文件加載與解析過程拉岁。
一般情況下坷剧,Java類文件中包含多個(gè)不同的方法簽名,如果其他的類文件引用該類文件中的方法喊暖,方法簽名也會(huì)被復(fù)制到其類文件中惫企,也就是說(shuō),多個(gè)不同的類會(huì)同時(shí)包含相同的方法簽名陵叽,同樣地狞尔,大量的字符串常量在多個(gè)類文件中也被重復(fù)使用。
這些冗余信息會(huì)直接增加文件的體積巩掺,同時(shí)也會(huì)嚴(yán)重影響虛擬機(jī)解析文件的效率偏序。消除其中的冗余信息,重新組合形成一個(gè)常量池胖替,所有的類文件共享同一個(gè)常量池研儒。由于dx工具對(duì)常量池的壓縮豫缨,使 得相同的字符串,常量在DEX文件中只出現(xiàn)一次殉摔,從而減小了文件的體積州胳。
架構(gòu)
Java虛擬機(jī)基于棧架構(gòu),程序在運(yùn)行時(shí)虛擬機(jī)需要頻繁的從棧上讀取或?qū)懭霐?shù)據(jù)逸月, 這個(gè)過程需要更多的指令分派與內(nèi)存訪問次數(shù)栓撞,會(huì)耗費(fèi)不少CPU時(shí)間,對(duì)于像手機(jī) 設(shè)備資源有限的設(shè)備來(lái)說(shuō)碗硬,這是相當(dāng)大的一筆開銷瓤湘。Dalvik虛擬機(jī)基于寄存器架 構(gòu)。數(shù)據(jù)的訪問通過寄存器間直接傳遞恩尾,這樣的訪問方式比基于棧方式要快很多弛说。
跟ART的區(qū)別
DVM依靠JIT運(yùn)行時(shí)解析,ART在應(yīng)用安裝時(shí)就預(yù)編譯字節(jié)碼到機(jī)器語(yǔ)言翰意,這一機(jī)制叫Ahead-Of-Time (AOT)編譯木人,在移除解釋代碼這一過程 后,應(yīng)用程序執(zhí)行將更有效率冀偶,啟動(dòng)更快醒第。
垃圾回收機(jī)制
首先介紹下dalvik的GC的過程.主要有有四個(gè)過程:
- 當(dāng)gc被觸發(fā)時(shí)候,其會(huì)去查找所有活動(dòng)的對(duì)象,這個(gè)時(shí)候整個(gè)程序與虛擬機(jī)內(nèi)部 的所有線程就會(huì)掛起,這樣目的是在較少的堆棧里找到所引用的對(duì)象.需要注意 的是這個(gè)回收動(dòng)作和應(yīng)用程序非并發(fā)。
- gc對(duì)符合條件的對(duì)象進(jìn)行標(biāo)記
- gc對(duì)標(biāo)記的對(duì)象進(jìn)行回收
- 恢復(fù)所有線程的執(zhí)行現(xiàn)場(chǎng)繼續(xù)運(yùn)行
dalvik這么做的好處是,當(dāng)pause了之后,GC勢(shì)必是相當(dāng)快速的.但是如果出現(xiàn)GC頻 繁并且內(nèi)存吃緊勢(shì)必會(huì)導(dǎo)致UI卡頓,掉幀.操作不流暢等进鸠。
后來(lái)ART改善了這種GC方式 , 主要的改善點(diǎn)在將其非并發(fā)過程改變成了部分并發(fā). 還有就是對(duì)內(nèi)存的重新分配管理稠曼。
當(dāng)ART GC發(fā)生時(shí):
- GC將會(huì)鎖住Java堆,掃描并進(jìn)行標(biāo)記
- 標(biāo)記完畢釋放掉Java堆的鎖,并且掛起所有線程 3. GC對(duì)標(biāo)記的對(duì)象進(jìn)行回收
- 恢復(fù)所有線程的執(zhí)行現(xiàn)場(chǎng)繼續(xù)運(yùn)行
- 重復(fù)2-4直到結(jié)束
Dalvik內(nèi)存管理特點(diǎn)是:內(nèi)存碎片化嚴(yán)重,當(dāng)然這也是標(biāo)記清除算法帶來(lái)的弊端客年,
ART的解決:在ART中,在單獨(dú)的內(nèi)存空間存放large Object霞幅。同時(shí)ART將不連續(xù)的物理內(nèi)存塊進(jìn)行對(duì)齊.對(duì)齊了后內(nèi)存碎片化就得到了很好的解 決。