android虚拟机

首先,让我们来思考下面几个问题:

什么是Dalvik虚拟机?

Dalvik VMJVM有什么区别?

Dalvik VM有什么新的特点?

Dalvik VM的架构是怎么样的?

 

 

首先,我得承认第一个问题问得很傻:什么是Dalvik虚拟机?没有人给出过一个明确的定义,但是,我们似乎可以从人们对Java虚拟机的描述中得到些信息。

 

Java虚拟机(JVM)是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。它有自己完善的硬件架构(如处理器、堆栈、寄存器等),还具有相应的指令系统。使用“Java虚拟机”程序就是为了支持与操作系统无关、在任何系统中都可以运行的程序。

 

因此,我们不妨对Dalvik虚拟机作出这样的描述: 

Dalvik虚拟机是Android程序的虚拟机,是AndroidJava程序的运行基础。其指令集基于寄存器架构,执行其特有的文件格式——dex字节码来完成对象生命周期管理、堆栈管理、线程管理、安全异常管理、垃圾回收等重要功能。它的核心内容是实现库(libdvm.so),大体由C语言实现。依赖于Linux内核的一部分功能——线程机制、内存管理机制,能高效使用内存,并在低速CPU上表现出的高性能。每一个Android应用在底层都会对应一个独立的Dalvik虚拟机实例,其代码在虚拟机的解释下得以执行。

 

Dalvik虚拟机关系最密切的非JVM莫属,在Android源码readme文档中有这样一段话:Much of the code under this directory originally came from the Apache Harmony project, and as such contains the standard Apache header comment. Some of the code was written originally for the Android project

Dalvik VMApache Harmony 项目关系源远流长,因此,与JVM关系自然就密切了。

 

 

 

 

然而:Dalvik VM Java VM

dalvik基于寄存器,而JVM基于stack 

Dalvik执行的是特有的DEX文件格式,而JVM运行的是*.class文件格式。

优势:1、在编译时提前优化代码而不是等到运行时

        2、 虚拟机很小,使用的空间也小;被设计来满足可高效运行多种虚拟机实例。

3、常量池已被修改为只使用32位的索引,以 简化解释器

 

 

JVM的字节码主要是零地址形式的,概念上说JVM是基于栈的架构。Google Android平台上的应用程序的主要开发语言是Java,通过其中的Dalvik VM来运行Java程序。为了能正确实现语义,Dalvik VM的许多设计都考虑到与JVM的兼容性;但它却采用了基于寄存器的架构,其字节码主要是二地址/三地址的混合形式。

基于栈与基于寄存器的架构,谁更快?现在实际的处理器,大多都是基于寄存器的架构,从侧面反映出基于寄存器比基于栈的架构更与实际的处理器接近。但对于VM来说,源架构的求值栈或者寄存器都可能是用实际机器的内存来模拟的,所以性能特性与实际硬件又有不同。一般认为基于寄存器架构的Dalvik VM比基于栈架构JVM执行效率更高,原因是:虽然零地址指令更紧凑,但完成操作需要更多的load/store指令,也意味着更多的指令分派(instruction dispatch)次数与内存访问次数;访问内存是执行速度的一个重要瓶颈,二地址或三地址指令虽然每条指令占的空间较多,但总体来说可以用更少的指令完成操作,指令分派与内存访问次数都较少。 

我们从下面的截图可以明了的看到与同一段Java代码对应的Java bytecode Dalvid bytecode的比较。

 

 

 

 

专有的DEX文件格式

一个应用中会定义很多类,

编译完成后即会有很多相应

CLASS文件,CLASS文件

间会有不少冗余的信息。

dex字节码和标准Java的字节码(Class)在结构上的一个区别是dex字节码将多个文件整合成一个,这样,除了减少整体的文件尺寸,I/O操作,也提高了类的查找速度。

原来每个类文件中的常量池现在由DEX文件中一个常量池来管理。

DEX文件可以进行进一步优化。优化主要是针对以下几个方面:

1、调整所有字段的字节序(LITTLE_ENDIAN)和对齐结构中的没一个域 

2、验证DEX文件中的所有类 

3、对一些特定的类进行优化,对方法里的操作码进行优化 

         优化 优化后的文件大小会有所增加,应该是原DEX文件的1-4倍。

       odex是为了在运行过程中进一步提高性能,对dex文件的进一步优化

 

 

 

 

一个应用,一个虚拟机实例,一个进程!!!

每一个Android应用都运行在一个Dalvik虚拟机实例里,而每一个虚拟机实例都是一个独立的进程空间。每个进程之间可以通信(IPCBinder机制实现)。虚拟机的线程机制,内存分配和管理,Mutex等等都是依赖底层操作系统而实现的。

 不同的应用在不同的进程空间里运行,当一个虚拟机关闭或意外中止时不会对其它 虚拟机造成影响,可以最大程度的保护应用的安全和独立运行。

 Zygote是虚拟机实例的孵化器。AndroidRuntime.cppZygoteInit.main()的执行会完成一个分裂,分裂出来的子进程继续初始化Java层的架构,这个分裂出来的进程就是system_server。每当系统要求执行一个Android应用程序,Zygote就会FORK出一个子进程来执行该应用程序。这样做的好处显而易见:Zygote进程是在系统启动时产生的,它会完成虚拟机的初始化,库的加载,预置类库的加载和初始化等等操作,而在系统需要一个新的虚拟机实例时,Zygote通过复制自身,最快速的提供个系统。另外,对于一些只读的系统库,所有虚拟机实例都和Zygote共享一块内存区域,大大节省了内存开销。

 

 

ART虚拟机

 

也许人们在得知Google新发布的Android系统版本名称为4.4时都不以为然,认为这个升级十分微不足道,只升级了0.1的版本号,启用了KitKat的新代号而已。就算是Google官方,对待此次升级也是颇为低调。可是如果了解了Android 4.4所暗示的变化时,我觉得所有Android开发者和其他利益相关者都必须打起十二分精神对看待Android 4.4了。

当官方发布Android KitKat 4.4时,我简单浏览了一下Google+上官方账户发布的对该系统的简介,觉得值得关注的只有两点:1)对内存的需求降低了,2)支持更多的 Sensor。综合起来,就是为可穿戴设备开路。确实没有更多的亮点可言,只是顺应了大的发展方向而已。随后我图个性价比,预定了Nexus 5,到手试用后第一感觉是“物美价廉”,对系统本身没有太大的感觉。

后来为了进行开发测试,我打开了“开发者模式”,其中有一个选项引起了我的注意,叫“选择运行时环境”,这是之前版本都没有的选项,可选项有Dalvik和ART(默认是Dalvik),Dalvik即Android一直以来使用的运行方式。为了弄明白这到底是个什么东西,我试着在Google上搜了一下,直接改变了我对4.4版本存在意义的看法。

简单地说,就是Android程序运行的根本机制改变了,程序会启动地更快,而且会更省资源。表现在用户体验上,就是Android更流畅了,同时续航能力显著增加。这种变化不是小打小闹,而是非常可观的大变化,根据AndroidPolicy上专项文章的说法,这个改变可以让部分Android程序的启动加速50%,理论上待机时间也会显著增加。

根据该文后一些“小白鼠”们的评论,他们在试用了ART运行模式后,都体会到了其带来的速度提升和续航提升,而且效果非常明显。这说明这个尚处在实验阶段的ART模式已经能够带来明显的好处,唯一不足的是,作为Beta版,稳定性欠佳。

众所周知,Android是基于Java语言的,iOS是基于Obejctive-C。表现在手机和应用程序运行机制上,Java的代码实际上需要 两次“转换”才能最终以用户可看的程序跑起来,一次发生在开发者发布安装包前,使用开发者自己机器的CPU,另一次在用户启动APP前,使用手机的 CPU。而基于Objective-C的代码只需要一次这种“转换”,在开发者发布安装包前,所以只占用开发者机器的CPU时间。

我们假设同样代码量的程序,需要同样多的CPU时间,进行从代码到最终能跑的“转换”。那么把这种工作全部放在了开发者的机器上进行的iOS显然就 更具优势,因为用户在打开APP之前不需要再浪费时间进行“转换”,这部分时间由开发者“忍受”了。而Android程序启动相对较慢就是因为第二次“转 化”需要在打开程序时进行引起的。这两种机制是历史的产物,总体上不能说谁好谁坏,只有适用范围的问题。考虑到手机属于体验要求比较高的设备,显然iOS 这种机制更合适。所以这两种机制带来的后果就是,iOS总是比Android快,而且是天生的。

现在ART的出现代表了什么?代表了Android在启动程序时将像iOS一样,无须进行第二次“转换”工作了。ART把第二次“转换”所要使用的 时间放在“程序安装时”进行,而不再是“程序启动时”进行。这样做虽然安装程序时要慢一点,但是在使用时就会明显快起来。按我的浅薄理解,就是把以前每次 启动程序都要做的工作改成“一次性”的工作,放在用户不那么在乎的安装时完成。这从长期来看也降低了总体的“转换”时间。

试想一个程序,安装后你使用了N次。按原先Dalvik的方法(术语叫Just-in-time compilation),N次启动就需要进行N次这样的“转换”。但是按照ART的方法(术语叫Ahead-of-time compilation),不管这个程序你使用几次,都只发生一次“转换”。这也解释了为什么使用ART会降低CPU的使用频率,进而降低电量的使用。

当然,ART也会带来其他的负面影响。其一是增加程序安装所需的时间,只是目前还不知道具体会是多少。考虑到其他技术因素,这个时长的增加可能比我 为了讲解方便所举的“第二次转换”所需的时长要长一点,但是肯定不会长到无法忍受的地步。据我查到的资料,这个变化对小程序几乎可以忽略不计,受影响的应 该是以游戏为主的程序,因为他们本身代码量就更大。不过这跟你获得的收益也是成正比的,因为ART可以让你在打开游戏时省更多的时间。如果将来都是“后台 安装”的话,对用户体验更是微乎其微,你去看几个新闻这时间就过去了。

第二个缺点是会使安装后的文件占用更多的空间,据称是10%-20%的增长。不过不要紧,这个增长指的是对“代码”部分文件的增加,比如一个 100M的游戏,可能代码只有20M,剩下80M是图片和音乐等文件,所以即便增加20%的安装所需空间,也只不过多了4M而已,在动辄16G,32G, 甚至128G容量的智能手机面前,影响更是微乎其微。

据我了解,ART这个项目其实在2年前就已经开始了,只不过之前一直不受关注,只有零星的报道,毕竟“计划不等于现实”嘛。可是现在Android 4.4版本以“开发者预览”的形式将其呈现出来,目的就是让手机厂商、应用开发者等进行测试,从而帮助该项目进行改进。从我得到的信息来看,ART的稳定 性并不差,完全可以胜任日常使用。

这也是为什么我会说,Android 4.4的ART选项可能预示着Android 5.0系统会出现重大改变——彻底从Dalvik转换到ART。 如果真的是这样的话,iOS开发人员和其用户所引以为傲的流畅体验将不再是一个值得炫耀的东西,因为这种体验将随着登陆Android平台变得“大众化”,再加上Android市场占有率的巨大优势、Google Play商店的崛起,iOS设备还能靠什么支撑自己的高价策略?

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值