谷歌究竟做了什么?

  • 来源:微型计算机
  • 关键字:谷歌,Android,Dalvik
  • 发布时间:2014-08-15 15:32

Android已经成为移动计算市场上最主要、占据市场份额最多的操作系统,从几百元的廉价手机到上万元的奢侈手机,人们都能找到Android的身影。不过,市场上的胜利并不能说明Android已经完美无缺了,在运行效率上,Android还有诸多问题,尤其是面对iOS时,Android的流畅性与稳定性还是与后者有些差距。为了改变这样的情况,谷歌在Android 4.4版本中加入了ART模式,在最近的谷歌I/O大会中,ART模式已经替代了Dalvik成为Android最主要的运行模式。

  6月份的谷歌I/O大会上,谷歌带来了最新的Android L操作系统。Android L除了对系统本身和界面做出大幅度改进外,还在应用程序的运行方式上做出了根本的变化_之前广泛使用的Dalvik模式被彻底抛弃,转而使用全新的ART(Android Runtime)模式。虽然这是一个软件模式上的改变,但是它将对所有使用Android系统的硬件都带来影响。那么,ART模式是什么?和Dalvik模式又有哪些不同呢?今天我们就深入了解—下这方面的内容。

  Dalvik,那个时代的选择

  说起Dalvik,就不得不提及Android初生的年代。如果对Android非常熟悉的用户,肯定还记得Android初生时所选用的设备-HTC Dream G1。这款手机的性能在今天看起来是如此的不堪:高通MSM7201A SoC芯片、192MB RAM。尤其值得一提的是高通MSM7201A,这颗处理器架构属于ARM11家族,它是目前的ARMv7架构的Cortex-A家族的上一代,被称作ARMv6架构。一个典型的ARMv6架构处理器拥有八级流水线、64KB L1缓存,没有L2缓存,典型的性能指标为0.7DMIPS/MHz,MSM72071A的性能大约为300DMIPS,目前的比较常见的处理器如三星Exynos 5420的性能值如果用类似方法勉强衡量性能的话,应该在30000DMIPS左右。

  也就是说,在2008年,谷歌希望自己的操作系统运行在只有目前主流芯片大约一百分之一性能的硬件上,同时还需要保证体验不至于太差。因此,谷歌必须要找到一种在低性能硬件、较低内存下也能满足使用体验的软件实现方式,并且这种软件实现方式还需要具有一定的通用性,以保证Android未来的发展。

  谷歌在研究后发现,要实现所有的功能并且要在较低的硬件配置上呈现出可用的、体验出色的高性能,只有Dalvik虚拟机能够满足需求。什么是虚拟机呢?虚拟机是一个虚构出来的计算机,它通过在实际的计算机上仿真模拟计算机的各种功能来实现。虚拟机有自己虚拟出来的处理器、堆栈、寄存器以及相应的指令系统。比如目前最常见的Java虚拟机的目的就是使得应用程序可以运行在任何场合和任何操作系统上。

  Dalvik虚拟机的发明人是Dan Bornstein,Dalvik这个名称来源于Dan Bornstein的祖先曾经在冰岛居住过的一个渔村。Dalvik虚拟机是Android中Java程序运行的基础,它的指令集基于寄存器架构,核心内容是实现库,所有的安卓程序都是运行在Dalvik虚拟机中,有多少个应用程序,就有多少个Dalvik虚拟机在运行。Dalvik虚拟机还有一些显著的特点,比如虚拟机特别小,占用空间也很小、运行效率高,一些数据表明,Dalvik虚拟机相比其他类型的虚拟机(比如堆栈虚拟机),能够减少47%的字节码数、内存访问时间减少37%、执行时间减少32%;Dalvik虚拟机独有dex文件格式,冗余信息少,空间占用低;Dalvik虚拟机使用了定制的Bionic库,容量只有200KB,运行效率非常高;Dalvik虚拟机使用32位的索引以简化解释器等。总的来看,Dalvik虚拟机可以高效的在Android的软硬件环境中运行。在使用了Dalvik虚拟机后,Android在性能较差的设备上运行的很不错。从此之后,Android的发展就顺风顺水,一路向前了。

  ART中AOT编译浮现,解决性能问题

  Dalvik虚拟机的出现,使得Android解决了在较低性能硬件上运行应用程序的根本问题,随后的Android 2.2上,Dalvik虚拟机又加入了即时编译器,也就是人们熟知的‘Just-ln-Time Compiler”。JIT的作用是对程序运行进行实时的跟踪分析,再根据运行情况直接编译最常用的代码为机器码。从Android 2.2开始一直到Android 4.4,JIT搭配Dalvik虚拟机,成为整个安卓系统运行的根本。在每次安卓系统升级的时候,人们看到的系统将应用程序一个个更新的界面,就是Android正在对虚拟机的文件进行优化以适应新版本的系统。

  不过随着Android的版本更新尤其是硬件性能的提升,JIT模式的问题也逐渐暴露出来,那就是性能损失比较严重。Android中运行任何程序时,都需要使用JIT编译器编译后运行,而且是每次运行都需要重新编译(这也是为什么很多后台内存清理软件实际上并不能真的带来效率与性能上的提升、并有可能浪费电能的根本原因——当然,如果这些软件没有胡乱联网并真的只是“驻留”的话)。不仅如此,JIT的即时编译模式,也使得CPU往往需要不停地跟随应用程序的运作而即时编译,对降低CPU占用率和节能也是不利的。

  鉴于此情况,谷歌在Android 4.4版本中引入了ART(Android Runtime)。相比Dalvik虚拟机,ART不但兼容之前的JIT,也加入了全新的AOT(Ahead-of-time预先编译)。其中的预先编译就是Android解决性能问题的根本。预先编译可以使得应用程序在安装的时候就将需要使用的程序编译为机器码并存储起来,在使用时直接调用机器码不再多次编译。这样一来,系统在运行时的绝大部分性能就可以集中在应用程序本身上,而不是编译内容上来,CPU由于负荷降低,也会降低使用频率,减少能耗。

  在兼容性方面,ART完全兼容之前Dalvik虚拟机的dex格式,因此软件开发者可以继续使用自己的开发方式,不过文件方面ART使用了“dex20at”替代了之前的“dexopt”,经过优化的“dexopt”文件也不再使用,转而改用新的ELF文件格式。在知识产权保护方面,ART也有积极的意义,ART的启用,将使得应用程序反编译和盗版的难度大幅度提升,这也是谷歌对知识产权保护的一种态度。在之前的Dalvik虚拟机中,恶意程序人员可以比较容易地将执行的机器码反编译为dexopt文件,从而盗取APK的核心信息。在ART模式启用后,由于谷歌严格控制了编译内容,因此反编译变得更难以操作。

  总的来看,ART中的AOT模式带来了很显著的优点,不过也有一些缺点存在,那就是由于应用程序会预先编译,因此安装时间会显著加长,不过在安装完成后的使用中,速度会更快、也会更为省电。一些实际测试结果也证明了这个论点,以Android 4.4为例,在有关Linpack的测试中,ART要比之前的Dalvik快大约30%,在Caffeninemark这样有关Java的测试中,差距进一步拉大到了50%。为了更清晰地证明这一点,谷歌自己也在最新的Android L上进行了测试,相比Android 4.4,新的Android L上ART下性能增幅更为明显,最高在诸如Chessbench中,可以达到之前Dalvik模式下几乎一倍还多的性能提升,令人惊讶!

  更流畅!垃圾回收方式彻底改变

  当然,ART中引入了AOT后会降低系统开销,提高效率并减少能耗。但仅仅从这一个方面入手还不能彻底改变目前Android有关流畅性的争论。为了进一步改进Android系统的使用感受,谷歌在引入了ART后,也对整个系统的垃圾回收方式进行了彻底的改进。

  在之前版本的Android上,内存管理是完全自动的,程序员根本不需要考虑物理内存的使用情况,这也是高级编程语言和低级编程语言的一个重要区别。当然,这样的优点很明显,开发人员不需要多在内存上操心,缺点也同样明显,开发人员不能控制内存操作,系统的自动化往往会带来不正确的结果。

  举例来说,在Dalvik模式下,垃圾回收机制是比较死板的。当应用程序发现没有足够内存使用时,Dalvik的垃圾回收机制会查找所有的堆栈,并且标记所有正在使用的对象,然后将那些没有使用的全部清空以供目前的应用使用。这个阶段中会有两次系统暂停出现,一次出现在查询所有堆栈时,另一次是在标记所有堆栈时。所谓暂停,是指在进行这两项工作时,所有的代码执行都会停止。一般来说这个时间会非常短暂,用户感觉不刭,但是总有例外,表现在设备上就是我们所说的卡顿现象。

  谷歌在Nexus 5上测试了Dalvik有关垃圾回收的内容,Dalvik在Nexus 5上每次暂停的时间平均是54ms——这只是一个平均值,在很多情况下应用程序写的很糟糕,这个时间甚至延长到人们直接可以感觉出来。不过即使是54ms,情况也不会很好,因为以比较流畅的60帧作为评价标准的话,一帧时间大约是16ms,54ms差不多相当于4帧时间,这已经比较长了。

  Anandtech测试了不同的应用在Dalvik和ART下的差异。首先是游戏。FIFA游戏在Dalvik环境下应用启动后,Dalvik的垃圾回收运行了多达9次,其中最短的一次暂停是4ms,最长的一次暂停了168ms,甚至还有由于线程阻塞系统不得不直接跳过38帧数(简直是悲剧)。最后统计的结果是,Dalvik的垃圾回收机制带来了至少603ms的暂停时间以及丢失了214帧。随后测试人员在ART模式下测试了游戏运行情况。这次表现得好很多。最短暂定186us,最长暂停6.139ms。总计暂停了4次,总暂停时间为12.364ms,丢失的帧数降低到了63帧,不过由于线程阻塞等问题,还是分别跳过了33帧和30帧。

  从上述测试结果来看,ART带来的优势还是相当明显的。谷歌宣称他们彻底改进了ART的垃圾回收机制,首先是只需要在标记使用对象时暂停,并且暂停时间被大大缩短,同时在查找堆栈时不再需要暂停了;其次,谷歌使用了名为Packard Pre-Cleaning的新技术使得很多工作在暂停前就已经完成,因此最终效果表现如此令人满意。相比Dalvik的平均54ms的暂停,在ART模式下,谷歌宣称平均暂停时间降低到了3ms,极大地提升了系统的流畅度。

  再比如Hangouts视频聊天应用。这类应用会造成大量的碎片文件,导致垃圾回收机制频繁启用,内存却没有足够的连续分区使用。因此只要降低碎片量、并使用更智能的内存分配系统就能大大减少垃圾回收机制的启用。在Dalvik模式下,最长暂停时间为27ms,最短为3ms,总计暂停了5次共90ms。在ART模式下这个数据被极大地降低了。总计检测到一次暂停,时间为961us,还不到1秒。

  在这里,暂停时间的缩短来自于两个方面,一个是新的内存分配机制,一个是ART本身。据估计ART带来了大约25%的性能提升。新的内存分配器被称之为“Rosalloc”,全称是“Runs-of-Slots-Allocator”,它替代了传统的“malloc”,不过谷歌并没有非常明确地宣称这一点。当然,无论如何,在ART中,人们看到了实实在在的性能提升,整体使用感受也更为出色,这样谷歌的目的就达到了。

  性能大提升-ART64位值得期待

  从上文的描述来看,ART是一个非常令人惊喜的、充满了前景的技术,它自然也会对各种各样当前常见的架构提供支持。目前ART已经支持了‘ARM、x86和MIPS的32位架构,对64位的架构支持方面,ART支持ARM64、x86-64、MIPS64等常见的64位架构。

  64位相比32位,带来的是更大的寻址空间并且能够普遍提高性能,同时大幅度提升加密功能的性能并保持和目前32位软件的兼容性。和苹果不同的是,谷歌在64位技术上使用了指针压缩,避免在64位应用下占据过多的内存空间,虚拟机方面依1日保留32位指针。

  为了进一步展示64位ART的性能,谷歌对比了在x86平台和ARM平台上运行32位和64位应用程序的性能差异,总体来看,在x86(也就是英特尔的BayTrail)平台上,新的平台展示出了2~4.5倍的性能优势,在ARM端的加密测试中也展示出了最高15倍的性能提升。在另一个被称为“Panorama”测试中,64位产品带来了大约13~l9%的性能增幅。

  64位的性能值得期待,谷歌也宣称从32位迁移到64位是非常简单的。谷歌给出了一个数据,目前在GooglePlay上的应用85%可以转移到64位,剩下的15%需要重新编译。总的来说谷歌认为64位迁移会在短时间内完成。

  因此,从上文的介绍和一些测试我们都可以看出,谷歌在Android L上全面引入ART是早有预谋的,ART的加入,不仅彻底改变了Android系统存在的问题,还同时带来了明显的性能提升。此外,在诸如知识产权保护、电池续航时间延长方面,ART都不负众望。总的来说,Android L以及ART的加入,是谷歌在Android发展中最重要的一次变革,而它的影响随着时间的增长,在未来三四年后更是会全面地体现出来。

关注读览天下微信, 100万篇深度好文, 等你来看……