浅谈Android的ART虚拟机

Android操作系统从2007年最初发布至今,已成为市场份额超过iOS的全球第一大移动操作系统。

越用越慢的Android系统

随着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时,安装时间也明显变长。但在手机硬件配置越来越高的今天,与获得更佳的系统性能相比,这个缺点也就不那么引人注目了。

本文作者:蔡欣(点融黑帮),现任点融网Android开发工程师。毕业于北京邮电大学,曾就职于UTStarcom、创新工场,多年来一直致力于手机系统软件及移动应用开发。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,444评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,421评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,363评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,460评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,502评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,511评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,280评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,736评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,014评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,190评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,848评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,531评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,159评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,411评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,067评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,078评论 2 352

推荐阅读更多精彩内容