Dalvik是Google公司自己设计用于Android平台的虚拟机。Dalvik虚拟机是Google等厂商合作开发的Android移动设备平台的核心组成部分之一。
它可以支持已转换为 .dex(即Dalvik Executable)格式的Java应用程序的运行,.dex格式是专为Dalvik设计的一种压缩格式,适合内存和处理器速度有限的系统。
Dalvik 经过优化,允许在有限的内存中同时运行多个虚拟机的实例,并且每一个Dalvik 应用作为一个独立的Linux 进程执行。独立的进程可以防止在虚拟机崩溃的时候所有程序都被关闭。
而这个.dex文件则是由Java字节码通过Android的dx工具生成的文件。
Dalvik 基于寄存器,而 JVM 基于栈。
基于寄存器的虚拟机对于编译后变大的程序来说,在它们执行的时候,花费的时间更短。
Dalvik虚拟机会在APP打开时去运行.dex文件,而这个是实时的,也就是JIT特性(Just In Time)。但这也会导致在启动APP时,会先将.dex文件转换成机器码,导致了APP启动慢的问题。
ART是Android Runtime,在Android5.0开始使用ART虚拟机来替代Dalvik虚拟机。
ART (ahead of time)引入了预先编译机制,可提高应用的性能。
这个机制可以在安装APK的时候将dex直接处理成可直接供ART虚拟机使用的机器码,ART虚拟机将.dex文件转换成可直接运行的.oat文件。ART虚拟机天生支持多dex,所以ART虚拟机可以很大提升APP的冷启动速度。
在安装时,ART 使用设备自带的 dex2oat 工具来编译应用。这工具接受 DEX 文件作为输入,并为目标设备生成经过编译的应用可执行文件。该工具可以顺利编译所有有效的 DEX 文件。但是,一些后处理工具会生成无效文件,Dalvik 可以接受这些文件,但 ART 无法编译这些文件。
以下来自官方:
“ART 和 Dalvik 是运行 Dex 字节码的兼容运行时,因此针对 Dalvik 开发的应用也能在 ART
环境中运作。不过,Dalvik 采用的一些技术并不适用于 ART。”
” ART 的 JNI 比 Dalvik 的 JNI 更为严格一些。使用 CheckJNI 模式来捕获常见问题是一种特别实用的方法。如果您的应用使用 C/C++ 代码。“
在 Android Runtime (ART) 中验证应用行为
垃圾回收 (GC) 会耗费大量资源,这可能有损于应用性能,导致显示不稳定、界面响应速度缓慢以及其他问题。ART 通过以下几种方式对垃圾回收做了优化:
ART 还具有比 Dalvik 更严格的安装时验证。
ART 提供了大量功能来优化应用开发和调试。
一直以来,开发者都使用 Traceview 工具(用于跟踪应用执行情况)作为分析器。虽然 Traceview 可提供有用的信息,但每次方法调用产生的开销会导致 Dalvik 分析结果出现偏差,而且使用该工具明显会影响运行时性能。
ART 添加了对没有这些限制的专用采样分析器的支持,因而可更准确地了解应用执行情况,而不会明显减慢速度。KitKat 版本为 Dalvik 的 Traceview 添加了采样支持。
ART 支持许多新的调试选项,特别是与监控和垃圾回收相关的功能:
当发生运行时异常时,ART 会为您提供尽可能多的上下文和详细信息。ART 会提供 java.lang.ClassCastException、java.lang.ClassNotFoundException 和 java.lang.NullPointerException 的更多异常详细信息。(较高版本的 Dalvik 会提供 java.lang.ArrayIndexOutOfBoundsException 和 java.lang.ArrayStoreException 的更多异常详细信息,这些信息现在包括数组大小和越界偏移量;ART 也提供这类信息。)
例如,java.lang.NullPointerException 现在会显示有关应用尝试处理 null 指针时所执行操作的信息,例如应用尝试写入的字段或尝试调用的方法。一些典型示例如下:
java.lang.NullPointerException: Attempt to write to field 'int
android.accessibilityservice.AccessibilityServiceInfo.flags' on a null object
reference
java.lang.NullPointerException: Attempt to invoke virtual method
'java.lang.String java.lang.Object.toString()' on a null object reference
ART 还通过纳入 Java 和原生堆栈信息,在应用原生代码崩溃报告中提供更实用的上下文信息。
之前在写dalvik虚拟机机器写JNI代码的时候要是crash的话只能在logcat里面看到抛出的一个信号量,ART支持堆栈打印的话,那毫无疑问可以大大提高我们写native代码的效率了。
参考资料:
https://source.android.com/docs/core/runtime?hl=zh-cn
https://developer.android.com/guide/practices/verifying-apps-art.html?hl=zh-cn#GC_Migration
https://baike.baidu.com/item/Dalvik/1996430
https://juejin.cn/post/7078164422761381918