Android Dalvik虚拟机

任何现代智能手机平台的成功很大程度上取决于其吸引开发人员加入该平台并推动相应硬件销售的能力。 Android在这方面取得了广泛的成功,这在很大程度上要归功于使用Java作为其主要语言(android-scripting项目使脚本语言能够针对Dalvik字节码,并且最近,Native Development Toolkit(NDK)中已添加了全面支持C / C ++。)。 Google之所以选择Java,是因为开发者社区众多(在撰写本文时,Java在TIOBE索引中目前排名第一)并且与其他移动语言(例如C ++(Symbian)和Objective-C(iPhone))相比,其相对易用性。

但是,Dalvik实际上不是真正的Java平台。 Android使用Java语言和开源Apache Harmony库(除了它们自己的库之外)以Java虚拟机(JVM)字节码生成标准类文件。 然后将这些类文件转换为Dalvik字节码,并存储在单个dex文件中。 这意味着并非所有Java代码都可以直接移植到Dalvik。 尽管实际上有很多可能,因为大多数J2SE标准库都可用,但Swing和AWT除外。 所以您可能会问自己,为什么要重新发明*? 我们已经拥有J2SE和J2ME,这两个都足够了。 Google支持Dalvik的动机实际上是基于多种因素:

有限的资源

智能手机系统与台式机或笔记本电脑表亲非常不同。 驱动设计决策的三个主要差异是:电池功率,无源冷却和小尺寸。 依靠电池意味着能源非常宝贵,必须积极节约。 被动冷却限制了在任何给定时间可以使用的电量,以避免导致设备变得不可接受的高温。 最后,体积小巧的价格给系统组件的组件尺寸带来了压力,并限制了可行的电池存储量。 更糟糕的是,电池密度的增长(即给定体积的能量)并未跟上移动硬件技术的发展。

如果管理不当,这种差异会导致系统很容易耗尽内存或耗尽电池。 例如,低端Android手机(表1)具有相对较慢的ARM处理器,其时钟速度在500 MHz范围内,不支持浮点运算,少量的RAM(通常低至128MB),没有操作系统交换空间和相对有限的外部闪存(通常是NAND),更重要的是适度的读取时间。 显然,我们不能简单地使用与功能强大得多的台式机或笔记本电脑相同的虚拟机。

Android Dalvik虚拟机

J2ME的问题

鉴于这些有限的资源,J2ME似乎是该平台的理想选择。 不幸的是,J2ME实际上已经过时了。 该平台的许多可选配置文件和扩展名导致现代智能手机应用程序的关键功能(例如蓝牙,SIP和3D图形)仅在部分J2ME手机上可用。 与iPhone和Android等平台(对于给定版本的操作系统,所有电话均支持大多数功能)相比,这种异构性对应用程序开发人员来说没有吸引力。 即使可以克服这一挑战,Java规范请求(JSR)流程也是包含新功能所需的漫长而官僚的流程。 相比之下,Google和拥有iOS的Apple一样,拥有完全的控制权,并且可以更快,更简化地推动新功能的采用。 最后,Java过去在移动平台上取得的成功有限的大部分原因是由于移动Java平台的速度太快了,而Java平台的设计目的并不是要利用当今的智能手机设备。 因此,Google不再使用现有的Java虚拟机之一,而是选择开发自己的自定义洁净室虚拟机。

许可问题

Oracle的J2SE虚拟机OpenJDK是使用GNU公共许可证版本2(GPLv2)许可的。 但是,许可证中存在一个限制,该限制使虚拟机上运行的应用程序不受GPL的“ Copyleft”条款的“感染”。 Copyleft将要求应用程序具有与虚拟机本身相同的许可证。 相反,J2ME虚拟机不包括此限制。

手机制造商当然会对发布其所有应用程序源代码的可能性感到厌恶,因此,Oracle通过收取一定费用来提供他们的TCK许可证,从而避免了这种义务,从而获得了大量收入。 甚至Apache的Harmony J2SE VM(可以很容易地转变为J2ME虚拟机)也具有有限的使用范围,迫使手机供应商购买J2ME许可证而不是自己购买。 Google断言Dalvik避免了这项义务,但是Oracle表示不同意,并已提起诉讼以为其索赔辩护。

开源的

谷歌针对Android的商业模式是将其作为开源和免费平台予以赠送。 他们的目标不是维持直接增长的收入,而是保持对不断增长的智能手机市场的访问,以获取其服务,更重要的是广告。 考虑到这一目标,Dalvik使用非常商业友好的Apache License 2.0进行许可,因为它不需要修改,也不需要在同一许可下发布衍生作品。 这使公司可以免费使用代码构建和部署专有产品。 此外,它允许社区将代码用于免费和开源软件。

安全

移动设备包含大量有关用户的敏感信息:电话号码,通话记录,地理位置等。因此,人们期望智能手机比传统功能手机具有更高的安全级别来保护此数据。 为了应对这些担忧,Dalvik旨在利用Linux内核强大的安全模型,使每个VM实例都在自己的进程中运行。 这些沙箱彼此之间相互影响,从而在应用程序之间建立了强大的屏障。

实作

现在我们了解了创建Dalvik的动机,我们将讨论Dalvik定制如何通过优化字节码文件大小,解释器速度和内存使用来为移动平台增加其设计。 此外,我们还将看到安全模型如何影响垃圾收集器和流程初始化程序Zygote的设计。

敏捷文件大小

Dalvik的dex二进制文件包含所有翻译后的Java类文件,这些文件合并为一个文件。 每个文件不分开的原因是为了减少总存储容量。 这是可能的,因为每个类文件都包含常量池,常量池对于应用程序来说是多余的,并且通常是类文件的最大部分。 将所有这些类一起使用时,可以删除文件之间共享的冗余常量值,并且只需要一个副本。 这种方法允许将相同的代码存储在与相同类文件的压缩jar所需的空间大致相同的空间中。 通过合并,Dalvik可以消除对文件进行解压缩的需求,从而提高性能(图1)。

Android Dalvik虚拟机

口译员速度

去年在Google I / O会议上,Dalvik团队向Dalvik宣布了即时(JIT)编译器。 此新增功能使开发人员无需依靠使用本机开发工具包(NDK)并用C / C ++重写其代码即可提高Java代码的性能。 与大多数JIT编译器相比,Android团队选择实现代码跟踪优化,而不是基于更常见的方法优化。

跟踪是通常通过多种方法一起执行的一系列指令。 例如,在一个Android游戏中,我们可能有一个重绘线程,该线程定期将更新对象列表绘制到画布上。 此跟踪将遍历多个类方法,并且应该非常快,使其成为JIT优化的理想选择。 如前所述,Android在内存和CPU能力方面都在资源受限的系统上运行。 因此,该团队选择在运行时识别热迹线以进行优化,而不是使用更多的内存来优化整个方法。 这些跟踪是本地编译的,然后放在翻译缓存中以备将来使用。 在翻译应用程序的各个部分时,执行开始从翻译缓存到解释器来回跳转。 对于背对背执行的热跟踪,执行将在高速缓存条目之间跳转,并且在没有所需代码的转换可用之前,该返回不会返回到解释器。 出于安全性和简化性的考虑,另一个设计选择要求每个单独的进程都有自己的转换缓存。

合子

Zygote允许多个Dalvik实例共享内存,以限制同时运行的每个实例的内存负担。 顾名思义,Zygote的目的是为新应用程序提供预加载的Android流程,而不会引起从头开始的延迟。 在Zygote初始化期间,核心类被预加载到内存中,以允许更快地启动应用程序。 由于每个Zygote都使用copyon-write共享内存空间,因此每个应用程序的大部分内存都可以重复使用,从而减轻了设备有限资源的负担。 这之所以起作用,是因为这些核心类大多是只读的,并且对于所有应用程序很少需要多个版本。 与典型的Java虚拟机相比,这在性能和内存效率上有很大的提高,因为它们没有实例之间共享这种类型的内存。 一旦加载了类,Dalvik VM本身便会初始化,并准备从dex文件运行Dalvik字节码。 一旦Zygote被新应用程序占用,另一个Zygote将被派生等待一个套接字,以启动下一个应用程序。

垃圾收集

为了执行垃圾收集,解释器需要保存一个表示可以收集对象的时间的位,即所谓的“标记位”。 这些位可以存储在内存中对象旁边或一起存储在单个表中。 由于内存非常有限,因此必须在进程之间保持尽可能多的共享内存,这一点很重要。 这意味着Dalvik必须避免通过更改单独对象(实际上是同一对象)中各个对象的标记位来生成私有副本。 相反,虚拟机在每个进程中使用单个表,该表允许对象在内存中作为单个副本保持共享,除非在复制对象时对其进行了修改。 相比之下,对所有过程使用单个表可能需要将对象保留的时间长于必要时间,更重要的是,显着增加了设计复杂性。

性能

Google声称Dalvik的速度是Oracle虚拟机的两倍,这归功于其基于寄存器的设计和更具表达力的说明。 与基于堆栈的Oracle虚拟机相反,Dalvik而是基于寄存器的。 大多数核心系统库的本机编译带来了其他改进,从而允许库操作以本机速度运行。 对于需要更高性能的应用程序,本机开发工具包(NDK)提供了完整的工具链,可以用C / C ++编写代码并编译为本机指令以加快执行速度。

结论

在本文中,我们看到了Dalvik虚拟机是如何定制设计的,以便为Android平台提供Java支持。 我们讨论了其创建背后的技术,安全和法律动机。 考虑到这些问题,我们还讨论了设计人员为优化解释器及其最终性能而做出的实施决策。 总体而言,Android将会保留下来,并且要充分利用该平台,任何开发人员都应该明智地了解Dalvik虚拟机平台对Java支持的基础。


翻译自: https://jaxenter.com/android-dalvik-virtual-machine-103063.html