art虚拟机介绍

  Android 4.4提供了一种与Dalvik截然不同的运行环境ART(Android runtime)支持,ART源于google收购的Flexycore的公司。ART模式与Dalvik模式最大的不同在于,启用ART模式后,系统在安装应用的时候会进行一次预编译,将字节码转换为机器语言存储在本地,这样在运行程序时就不会每次都进行一次编译了,执行效率也大大提升。这种编译的方式与c++,c语言编译方式蛮像。

  虚拟机切换设置

  Settings> Developer Options> Select Runtime

ART优点     
   1、系统性能的显著提升。     
   2、应用启动更快、运行更快、体验更流畅、触感反馈更及时。     
   3、更长的电池续航能力。
   4、支持更低的硬件。


ART缺点    
  1、更大的存储空间占用,可能会增加10%-20%。
  2、更长的应用安装时间。

Dalvik虚拟机性能优化
     1、DEX代码安装时或第一次动态加载时odex化处理。
     2、Android2.3版本提供了JIT机制提升性能;

      JIT(Just-In-Time),用来在运行时动态地将执行频率很高的dex字节码编译成本地机器码,然后再执行。通过JIT,就可以有效地提高Dalvik虚拟机的执行效率。但是,应用每次运行的时候,部分字节码都需要通过JIT转换为机器码,降低了应用程序运行效率。而ART则是使用AOT进行处理(Ahead-Of-Time),所谓AOT是指在运行以前就把中间代码静态编译成本地代码,这就减去了JIT运行时的转换时间,因此,即使Dalvik采用了JIT,Dalvik总体性能还是不能与直接执行本地机器码的ART虚拟机相比。

AOT的编译器分两种模式:
  1. 在开发机上编译预装应用;
          C/C++开发应用程序的时候,编译器直接就把它们翻译成目标机器码。
  2. 在设备上编译新安装的应用;
          在应用安装时将dex字节码翻译成本地机器码。

 art执行功能类图如下:

 

  通过上图我们可以总结出这样的结论:

  ①在JNI_CreateJavaVM()中,先是调用Create()函数来创建Runtime。Runtime是个单例,创建出来后紧接着调用Init()函数(/art/runtime/runtime.cc)。Init()函数会做很多初始化工作:解析参数,初始化Heap和JavaVMExt结构,线程和信号处理,创建ClassLinker等。

  ②接着调用ClassLinker的FindClass()查找目标类,其中涉及几个关键函数:LookupClass(),DefineClass(),InsertClass(),LoadClass()和LinkClass()。以下简要介绍下它们的主要功能:

  LookupClass()先在ClassLinker的成员变量class_table_中找指定类,找到就返回,找不到的话看是否要在image中找(class_loader为NULL且dex_cache_image_class_lookup_required为true)。如果要的话就调用LookupClassFromImage()在Image中进行查找,找到了就调用InsertClass()将找到的类放入到class_table_中方便下次查找。

  DefineClass()做了很多事情,包括了LoadClass(),InsertClass()和LinkClass()等动作。其中,LoadClass()调用LoadField()和LoadMethod()等函数把类中的域和方法数据从dex文件中读出来,填入Class结构。
  InsertClass()主要功能是把该类写入class_table_中方便下次查找。
  LinkClass()顾名思义,就是动态绑定虚函数和接口函数了。其调用结构:
  LinkSuperClass() // 检查父类。
  LinkMethods()
  LinkVirtualMethods() // 结合父类进行虚函数绑定,填写Class中的虚函数表vtable_。
  LinkInterfaceMethods() //处理接口类函数信息iftable_。注意接口类中的虚函数也会影响虚函数表,因此会更新vtable_。
  LinkInstanceFields() & LinkStaticFields() // 更新域信息,如域中的Offset和类的对象大小等。

  对于FindClass()来说,类大体有以下几种情况:内置类,启动类,系统类和其它。内置类是很基本的类,一般是初始化时预加载好的(如WellKnownClasses和JniConstants里那一坨),它们可以通过LookupClassFromImage()函数找到。启动类是在BOOTCLASSPATH里的类,由于它们是启动类,所以这里还没有ClassLoader。除掉前面的内置类,其余的通过DexFile::FindInClassPath()查找得到。再就是系统类和其它类,它们的加载过程是类似的,都是通过ClassLoader的loadClass方法,区别在于前者通过特殊的SystemClassLoader进行加载。举例来说,对于一个还没被加载过的启动类,一般流程是这样的:

posted on 2014-04-02 06:59  laozhu1124  阅读(10148)  评论(2编辑  收藏  举报

淘宝免费计数器