android L中正式将ART设为默认的runtime了,有必要对art做一下简单的了解。
主要参考android网站上的介绍:
http://source.android.com/devices/tech/dalvik/art.html
http://developer.android.com/guide/practices/verifying-apps-art.html
AOT 编译(ahead of time)
在安装时候,就会将java code编译成直接执行的机器码。这样会导致安装的时间变长,占用的空间变大,
但是在运行时候,速度会加快。编译是使用dex2oat这个tool来完成的。
GC改进
- gc过程中一次pause,而不是dalvik中所要的两次(concourrent gc)。
- 在一个gc pause的过程中,可以并行处理其他的gc。
- 对于特定的case,pause time有优化。
- 改进了gc的调度策略,让gc更加的及时,保证在典型的引用场景下,很少出现gc for malloc的情况。
- ART后续会引入compacting gc。(compact会引入一些问题,需要应用开发者注意)
开发和debug方面的改进
sampling profiler (tracerview)比以前更加的精确,因为ART减少了一些额外的时间开销(比如编译,比如gc)
art在gc和monitor方面增加了不少新的feature。(见google的说明)
VS dalvik JIT(just-in-time)
JIT是在运行时候进行编译,并放在cache内,所以在运行程序的时候,不时的需要去编译,会降低速度,并且
因为cache有限,不能保存所有的编译结果,所以运行中可能需要反复的编译。
ART和dalvik相比,在效率上很有优势的,主要问题就是因为会占用更多的空间,这在早期产品中可能很难接受(ROM才2G),
但是在现在的情况下,已经可以接受了。
额外的一个好处就是耗电量,因为编译的时间减少了,自然功耗也可以降低一点。
APP开发的注意
compacting gc
compacting gc顾名思义,在gc的时候会做compact,以为着对象会被从一个地方copy到另外一个地方来保存。这个机制对于
java层没有影响,但是对于jni会有很大的影响。
很多时候,jni中会记录一些java层对象的指针,比如数组的元素地址,这样在compacting gc后,地址会发生变化,而jni层还保留了旧的地址,去操作就会发生问题了。
art中对checkjni进行了扩展可以检测此类问题。
stack size
在dalvik中java stack和native stack是独立的,但是art中两者合二为一,那么app中要注意对于stack size的设置,要放大了。
art中check jni也会对stack size进行检查警告。
How to config ART
项目中可以配置如下方式
PRODUCT_RUNTIMES := runtime_libdvm_default
PRODUCT_RUNTIMES += runtime_libart