淺談Android的ART虛擬機

Android操作系統從2007年最初發布至今,已成為市場份額超過iOS的全球第一大移動操作系統。


黄大仙78345持码报:越用越慢的Android系統

码报开奖结果本期 www.iwqgw.icu 隨著Android用戶的不斷增多,它的一個重大弱點也一直為人所詬?。核孀攀褂檬奔淶腦齔?,系統會變得越來越慢。很多中高端的Android手機即使在硬件配置上比同時期的iPhone還要高不少,仍然會在長期使用之后變得反應遲鈍。

關于Android系統運行慢的原因眾說紛紜,其中大家公認的一個因素,就是Android使用的Dalvik虛擬機的性能問題。

因此Google在2014年推出了新的虛擬機ART,在Android4.4系統中提供給用戶試用,力圖從根本上改善系統卡頓的問題 ,并且從Android5.0開始廢棄了Dalvik,全面推行ART。

隨著越來越多Android5.0及以上機型的面世,很多終端用戶已經用上了配備ART虛擬機的Android系統。系統是否真的變快了,這還需要經過用戶的考驗,我們先看一下ART有哪些技術上的改進。

Dalvik和ART

眾所周知,Android系統是以Linux為內核構建的。Google為了降低應用的開發難度,并將其適配到不同硬件配置的設備上,在Linux內核之上構建了一個虛擬機,Android應用使用java開發,運行在虛擬機之上。

Dalvik就是Android4.4及之前使用的虛擬機,它使用的是JIT(Just-In-Time)技術來進行代碼轉譯,每次執行應用的時候,Dalvik將程序的代碼編譯為機器語言執行。隨著硬件水平的不斷發展以及人們對更高性能的需求,Dalvik虛擬機的不足日益突出。而應運而生的ART(Android RunTime)虛擬機,其處理機制根本上的區別是:它采用AOT(Ahead-Of-Time)技術,會在應用程序安裝時就轉換成機器語言,不再在執行時解釋,從而優化了應用運行的速度。在內存管理方面,ART也有比較大的改進,對內存分配和回收都做了算法優化,降低了內存碎片化程度,回收時間也得以縮短。

下圖是Google發布的使用不同性能測試工具時Dalvik和ART的得分對比:


ART運作原理

1) 內存管理

內存管理的優化是ART的一大改進。

ART虛擬機首先會從系統空間中取得足夠的空間,這些空間在沒有使用的時候并不占用物理內存,在使用的時候才分配物理內存,在不需要的時候及時歸還給系統。ART 將分配到的空間根據需要托管給不同的算法進行管理,主要提供了如下幾種分配算法來進行內存分配,它們的定義可以在ART源碼定義中看到:

enum AllocatorType {

kAllocatorTypeBumpPointer,  // Use BumpPointer allocator, has entrypoints.

kAllocatorTypeTLAB,  // Use TLAB allocator, has entrypoints.

kAllocatorTypeRosAlloc,  // Use RosAlloc allocator, has entrypoints.

kAllocatorTypeDlMalloc,  // Use dlmalloc allocator, has entrypoints.

kAllocatorTypeNonMoving,  // Special allocator for non moving objects, doesn't have entrypoints.

kAllocatorTypeLOS,  // Large object space, also doesn't have entrypoints.

};

其中后二種是沒有跳轉表(entrypoints)的,我們主要了解一下前面4種的分配策略:

RosAlloc(Rows of slots Allocator)的分配策略:在Ros Alloc Space分配對象,是一種線性分配方式,將一個大的連續空間劃分為多個片,每個片中只能分配固定大小的內存。這種分配方式有一個更加細粒度的結構,可以鎖定獨立的對象。

BumpPointer:在Bump Pointer Space中分配對象。每一次申請時,分配需要的size,返回end地址的值。然后將end后移sized,作為下一次申請的地址。這種分配采用不計數申請的方式,直到發生out of memory。采用Moving GC的方式進行回收。

TLAB(Thread Local Allocation Block):在由Bump Pointer Space提供的線程局部分配緩沖區中分配對象,按線程進行管理。每一個線程,從Bump Pointer Space中申請一個block,在線程內使用Bump Pointer的分配策略。由于每一個線程獨立在自己的block中分配內存,避免了同步,可以提高效率。

DLMalloc:這是原Dalvik使用的算法 。在Dl Malloc Space分配對象,將memory劃分成很多小的數據塊,每一個塊的前8個或者16個字節作為Header,使用鏈表來管理空閑的數據塊。

使用這些不同算法來分配內存,與Dalvik相比可以有效的減少碎片化,由于碎片化減少,相應也就減少了GC的次數。除此之外,像TLAB這樣的算法引入,也減少了申請內存時線程之間的競爭。

在內存回收方面,ART也提供了幾種GC算法,GC算法與內存分配算法相對應,關系如下表:


ART在回收memory時,會依據進程狀態選擇不同的算法。除此之外,ART在GC時采用了讀寫鎖的機制,減少了進程被掛起的時間,因此較之于Dalvik,GC時線程掛起的時間也相應縮短。

2) 代碼執行

我們引用一張Google的圖來看一下Android對apk的執行流程(圖片從上往下閱讀):


Java文件在編譯成class文件,然后經過Android平臺的dx工具轉換為Dex文件后,同Native code(JNI)和資源一起打包成apk,apk安裝到手機后解壓出Dex文件。Dalvik會通過dexopt工具將Dex優化,成為Odex文件,Odex文件的效率比Dex高,但其中大部分代碼仍然需要每次執行時編譯;而ART則會將Dex通過dex2oat工具編譯得到一個ELF文件,它是一個可執行的文件。

關于Java代碼的執行過程,以一段簡單的代碼為例:

int a = 1;

int b = 2;

public int test() {

① int x = a;

② int y = b;

int z = a + b;

return z;

}

在執行這段Java代碼時,Dalvik虛擬機先要把test()方法的每句代碼轉譯成Dex代碼,對其中的① ② 兩句賦值語句,執行時需要在虛擬機中進行“指令讀取—識別指令—跳轉—實例操作”的解析過程;而ART中Java代碼都被以方法為單位編譯成匯編指令,執行上面這個方法的時候,① ② 兩句代碼只需要直接拷貝兩個寄存器的值,各需要一條匯編指令就可以完成,省去了跳轉、指令讀取的過程,執行效率也就大大提高了。

總結

虛擬機從Dalvik換成ART后,Android系統的性能得到了一定程度的提升。不過ART與Dalvik相比也存在一些缺點,比較明顯的表現就是,apk經過dex2oat預編譯之后,占用的空間增加,因此Android ROM占用的空間更大。手機在安裝下載的apk時,安裝時間也明顯變長。但在手機硬件配置越來越高的今天,與獲得更佳的系統性能相比,這個缺點也就不那么引人注目了。


文/點融黑幫(簡書作者)
原文鏈接://www.jianshu.com/p/1f779586efdc

上一篇: VR進校園 谷歌英國為學子提供VR授課服務

下一篇: Android 插件還能這么玩!新系統的 4 個效率工具推薦

分享到: 更多
体彩排列五是有规律的 重庆时时彩大小计划免费 1000炮捕鱼游戏机技巧规律 七乐彩走势图近30期 pk10手机版软件下载 三D胆拖价格表 快乐十分任四稳赚技巧 幸运飞艇怎么稳赚 大乐透走势图表图30期 实体店开什么好 双面盘什么时候稳 幸运五分赛车怎么看走势图 时时彩计划软件苹果手机版 北京pk10赛车计划群 北京pk10走势图彩图 pk10最牛稳赚5码机