ART到底是不是虚拟机?

很多人都有一个疑问,既然Java代码已经在安装时全部翻译成了机器码,

存储为elf格式的可执行文件,虚拟机应该就没有存在的价值了。

实际上是不可能的。

早期的编译型语言与解释型语言的划分其实是一种初级的划分。

随着编译器的演变,不同类型的编译器都在互相取长补短。

编译型语言比如Object C,逐步采用引用计数器实现了内存管理的自动化,

而解释型语言也通过安装时执行翻译改善了性能。

作为解释型语言的JAVA,其ART虚拟机的主要工作是管理运行时类型信息,加载,卸载代码段,标记,回收内存等资源。

编译型语言如C语言是没有这些工作的。

基于ART运行的apk仍然会比编译型语言要慢。

apk代码翻译成机器码后,仍然没有直接运行,直接运行的代码仍然是ART虚拟机进程,虚拟机进程需要动态地加载机器码,执行机器码,动态地链接应用代码调用的运行时库。

ART与Dalvik相比,主要的改进是减少了字节码到机器码的翻译过程,这个优势主要体现在启动时。Dalvik本身就基于JIT,首次翻译字节码后,会把翻译好的机器码存储在缓存中,再次调用时不需要再次翻译。而ART的优势是在安装apk应用时完成所有的翻译工作,直接保存机器码。运行时直接动态加载。

与C语言代码相比,ART仍然要多做很多事情,首先是内存回收。其次,由于应用程序所依赖的运行时库的代码可能不在内存中,运行前需要经历代码加载过程,即使已经在内存中,也还需要进行地址计算。大量的加载和地址映射会显著影响运行性能。对于C语言来说,编译时大量的静态库已经链接起来,地址已经确定,内存分配过程也没有引用计数器的管理。

另外,Java语言本身有很多机制是需依赖运行时信息的,比如instanceof这样的关键字,在AOT编译时无法直接对应到机器码,需要调用ART虚拟机存储的运行时信息。这样的运行时信息的存储与更新也是一笔很大的开销。而C语言没有运行时信息,不会有这样的开销。

总的来说,ART虚拟机类似于在一个通用的进程中频繁地调用loadlibrary以运行整个应用程序。而C语言代码则在编译时链接了大部分代码,而很少调用loadlibrary,也没有内存回收机制。

你可能感兴趣的:(ART到底是不是虚拟机?)