android l art模式,Android ART模式简介

Android4.4最大的变化就是引入ART模式来代替Dalvik虚拟机。ART是Android

Runtime的缩写,它提供了以AOT(Ahead-Of-Time)的方式运行Android应用程序的机制。所谓AOT是指在运行前就把中间代码静态编译成本地代码,这就节省了JIT运行时的转换时间。因此,和采用JIT的Dalvik相比,ART模式在总体性能有了很大的提升,应用程序不但运行效率更高,耗电量更低,而且占用的内存也更少

ART和dalvik相比,系统的性能得到了显著提升,同时占用的内存更少,因此能支持配置更低的设备。但是ART模式下编译出来的文件会比以前增大10%-20%,系统需要更多的存储空间,同时因为在安装时要执行编译,应用的安装时间也比以前更长了。

ART和dalvik相比,系统的性能得到了显著提升,同时占用的内存更少,因此能支持配置更低的设备。但是ART模式下编译出来的文件会比以前增大10%-20%,系统需要更多的存储空间,同时因为在安装时要执行编译,应用的安装时间也比以前更长了。

开启ART模式

在Android中ART模式缺省是关闭的,如果我们希望启动ART模式,需要在“设置”应用中手工打开它。进入“设置”后,选择“开发者选项”,再点击“选择运行环境”,会弹出如选择DALVIK或ART的对话框。选择ART后,系统将会重新启动,然后系统的运行环境就会从Dalvik切换到ART模式。

让我们打开“设置”应用的代码,看看这种切换到底做了些什么。下面是DevelopmentSettings.java中的一段代码:

builder.setPositiveButton(android.R.string.ok, new

OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

SystemProperties.set(SELECT_RUNTIME_PROPERTY,

newRuntimeValue);

pokeSystemProperties();

PowerManager pm = (PowerManager)

context.getSystemService(Context.POWER_SERVICE);

pm.reboot(null);

}

});

上面这段代码只是设置重新设置了属性SELECT_RUNTIME_PROPERTY的值,然后就重启设备。这个属性的定义如下:

String SELECT_RUNTIME_PROPERTY = "persist.sys.dalvik.vm.lib"

注意属性是以persist开头的,所以它的值在重新开机后也可以保存。这个属性定义的是当前使用的运行环境库,如果是dalvik,它的值为libdvm.so,如果是art,它的值为libart.so。通过这个属性,系统就能判断出需要运行的模式。

ART系统的源码位于目录art下,包含了以下目录:

build目录:存放了一些mk文件。

compiler目录:动态库libart-compiler.so的源码目录,它包含了一个ART的编译器。

dalvikvm目录:可执行文件dalvikvm的源码目录。

dex2oat目录:可执行文件dex2oat的源码目录。用来将dex格式的文件编译成可执行文件。dex2oat文件会链接libart-compiler动态库。

jdwpspy目录:可执行文件jdwpspy的源码目录。这是一个调试工具,通过socket接收VM中输出的消息并打印输出。

oatdump目录:可执行文件oatdump的源码目录。这是一个工具,能dump出art文件的信息。

runtime目录:动态库libart.so的源码目录。

test目录:包含了大量测试代码的目录。

tools目录:包含了几个脚本文件。

两种模式的区别

从系统的实现角度看,ART和Dalvik的区别只表现在两个地方。一处是在安装应用执行优化时,Dalvik模式下执行的是dexopt程序,而ART模式下执行的是dex2oat程序。这个在“11.5.5节

dexopt(优化)命令”中已经介绍过来。通过dex2oat程序编译后得到的是elf格式的可执行文件,而不是以前的dalvik字节码了。

另一处是在运行应用时,Dalvik模式下系统为应用进程链接的是libdvm.so,而ART模式下链接的是libart.so。这两个库文件能够相互替换,是因为它们都实现了相同的接口。下面我们看看Android是如何来装载不同运行库的。

前面我们已经介绍过了,Zygote进程启动时会调用AndroidRuntime的start()函数来启动虚拟机,start()函数中有下面两行代码:

void AndroidRuntime::start(const char* className, const char*

options)

{

......

JniInvocation jni_invocation;

jni_invocation.Init(NULL);

......

}

我们看看jni_invocation的Init()函数的代码:

bool JniInvocation::Init(const char* library) {

#ifdef HAVE_ANDROID_OS

char default_library[PROPERTY_VALUE_MAX]; //

从property中得到运行库的名称

property_get(kLibrarySystemProperty,

default_library, kLibraryFallback);

#else

const char* default_library =

kLibraryFallback;

#endif

if (library == NULL) {

library =

default_library;

}

handle_ = dlopen(library,

RTLD_NOW); // 装载运行库

if (handle_ == NULL) {

...... //

错误处理

}

// 装载三个VM的入口函数。

if

(!FindSymbol(reinterpret_cast(&JNI_GetDefaultJavaVMInitArgs_),

"JNI_GetDefaultJavaVMInitArgs")) {

return

false;

}

if

(!FindSymbol(reinterpret_cast(&JNI_CreateJavaVM_),

"JNI_CreateJavaVM")) {

return

false;

}

if

(!FindSymbol(reinterpret_cast(&JNI_GetCreatedJavaVMs_),

"JNI_GetCreatedJavaVMs")) {

return

false;

}

return true;

}

JniInvocation的Init()函数中通过属性persist.sys.dalvik.vm.lib取得了运行库的名称,然后调用dlopen()来装载运行库,同时从动态库中读取了三个函数的地址,它们是JNI_GetDefaultJavaVMInitArgs(),JNI_CreateJavaVM()和JNI_GetCreatedJavaVMs()。这三个函数相当于是虚拟机的三个入口函数,通过调用它们,就能创建出虚拟机系统。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值