Android ART虚拟机
来源:互联网 发布:淘宝达人如何申请 编辑:程序博客网 时间:2024/06/16 18:06
- Android ART虚拟机
Android 4.4提供了一种与Dalvik截然不同的运行环境ART(Android runtime)支持,ART源于google收购的Flexycore的公司。ART模式与Dalvik模式最大的不同在于,启用ART模式后,系统在安装应用的时候会进行一次预编译,将字节码转换为机器语言存储在本地,这样在运行程序时就不会每次都进行一次编译了,执行效率也大大提升。
虚拟机切换设置
Settings> Developer Options> Select Runtime
<img src="http://www.2cto.com/uploadfile/Collfiles/20140118/2014011809022114.png" alt="" http:="" www.2cto.com="" kf="" ware="" vc="" "="" target="_blank" class="keylink" style="border-width: 0px; padding: 0px; margin: 0px; list-style: none; width: 240px; height: 400px;">vcC0tLS9qNOm08OzzNDyvfizzKOsyqHIpbXEsru99r32ysfTptPDs8zQ8r34s8y0tL2oRGFsdmlr0OnE4rv6tcTKsbzko6xaeWdvdGXNqLn9QW5kcm9pZFJ1dGltZTo6c3RhcnS6r8r9tLS9qERhbHZpa9DpxOK7+qGj1NpBbmRyb2lkz7XNs9bQo6xEYXZpa9DpxOK7+sq1z9bU2mxpYmR2bS5zb9bQo6xBUlTQ6cTiu/rKtc/W1NpsaWJhcnQuc2/W0KOszai5/XBlcnNpc3Quc3lzLmRhbHZpay52bS5saWLPtc2zyvTQ1MC00aHU8dTL0NDWuLao0OnE4rv6oaPO3sLbRGFsdmlru7nKx0FSVKOstrzKtc/WwcvI/bj2z+DNrLXEvdO/2rqvyv2jujxicj4KMS4gSk5JX0dldERlZmF1bHRKYXZhVk1Jbml0QXJncyAtLSC78cih0OnE4rv6tcTErMjPs/XKvLuvss7K/Txicj4KMi4gSk5JX0NyZWF0ZUphdmFWTSAtLSDU2r34s8zW0LS0vajQ6cTiu/rKtcD9PGJyPgozLiBKTklfR2V0Q3JlYXRlZEphdmFWTXMgLS0gu/HIob34s8zW0LS0vai1xNDpxOK7+sq1wP08YnI+Cgo8aW1nIHNyYz0="http://www.2cto.com/uploadfile/Collfiles/20140118/2014011809022218.jpg" alt="\">
JniInvocation提供统一了接口:
libnativehelper\JniInvocation.cppjint JniInvocation::JNI_GetDefaultJavaVMInitArgs(void* vmargs) { return JNI_GetDefaultJavaVMInitArgs_(vmargs);}jint JniInvocation::JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) { return JNI_CreateJavaVM_(p_vm, p_env, vm_args);}jint JniInvocation::JNI_GetCreatedJavaVMs(JavaVM** vms, jsize size, jsize* vm_count) { return JNI_GetCreatedJavaVMs_(vms, size, vm_count);}
该函数间接调用以下函数来实现:extern "C" jint JNI_GetDefaultJavaVMInitArgs(void* vm_args) { return JniInvocation::GetJniInvocation().JNI_GetDefaultJavaVMInitArgs(vm_args);}extern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) { return JniInvocation::GetJniInvocation().JNI_CreateJavaVM(p_vm, p_env, vm_args);}extern "C" jint JNI_GetCreatedJavaVMs(JavaVM** vms, jsize size, jsize* vm_count) { return JniInvocation::GetJniInvocation().JNI_GetCreatedJavaVMs(vms, size, vm_count);}
libnativehelper\JniInvocation.hstatic JniInvocation* jni_invocation_;void* handle_;//保存so库的首地址jint (*JNI_GetDefaultJavaVMInitArgs_)(void*);jint (*JNI_CreateJavaVM_)(JavaVM**, JNIEnv**, void*);jint (*JNI_GetCreatedJavaVMs_)(JavaVM**, jsize, jsize*);
因此JniInvocation对外提供的接口函数是由JniInvocation中定义的函数指针来实现。JniInvocation中定义的函数指针是在哪里初始化的呢?我们知道Android虚拟机是在Zygote进程中通过调用AndroidRuntime::start()函数启动的: frameworks\base\core\jni\AndroidRuntime.cppvoid AndroidRuntime::start(const char* className, const char* options){ ... /* start the virtual machine */ JniInvocation jni_invocation; jni_invocation.Init(NULL); JNIEnv* env; if (startVm(&mJavaVM, &env) != 0) { return; } onVmCreated(env);...}
在启动虚拟机前通过调用JniInvocation::Init()函数来初始化JniInvocation中声明的函数指针bool JniInvocation::Init(const char* library) {#ifdef HAVE_ANDROID_OS char default_library[PROPERTY_VALUE_MAX]; property_get("persist.sys.dalvik.vm.lib", default_library, "libdvm.so");#else const char* default_library = "libdvm.so";#endif if (library == NULL) { library = default_library; } handle_ = dlopen(library, RTLD_NOW); if (handle_ == NULL) { ALOGE("Failed to dlopen %s: %s", library, dlerror()); return false; } //查找JNI_GetDefaultJavaVMInitArgs函数指针 if (!FindSymbol(reinterpret_cast(&JNI_GetDefaultJavaVMInitArgs_), "JNI_GetDefaultJavaVMInitArgs")) { return false; } //查找JNI_CreateJavaVM函数指针 if (!FindSymbol(reinterpret_cast(&JNI_CreateJavaVM_), "JNI_CreateJavaVM")) { return false; } //查找JNI_GetCreatedJavaVMs函数指针 if (!FindSymbol(reinterpret_cast(&JNI_GetCreatedJavaVMs_), "JNI_GetCreatedJavaVMs")) { return false; } return true;}
该函数就是根据persist.sys.dalvik.vm.lib属性值来加载不同的虚拟机动态库,并从动态库中查找JNI_GetDefaultJavaVMInitArgs,JNI_CreateJavaVM,JNI_GetCreatedJavaVMs函数首地址bool JniInvocation::FindSymbol(void** pointer, const char* symbol) { *pointer = dlsym(handle_, symbol); if (*pointer == NULL) { ALOGE("Failed to find symbol %s: %s\n", symbol, dlerror()); dlclose(handle_); handle_ = NULL; return false; } return true;}
Dalvik字节码生成过程
应用安装时采用的代码优化方式不同:
Dalvik : dex2opt
ART : dex2oatART本地码生成过程
Dalvik dex代码经过dex => optimized dex => JIT cache这个过程,内存中需要同时容纳odex和JIT cache两份代码;换成ART以后,就变成dex => oat,内存里只放oat就可以。
两个运行环境产生的优化代码路径及文件名都为:/data/dalvik-cache/app/data@app@{package name}.apk@classes.dex,但是ART环境产生的优化代码文件大小明显比Dalvik环境产生大。OAT文件其实就是基于ELF格式的一种私有文件格式。
dex2oat编译过程
开发者开发出的应用程序经过编译和打包之后,仍然是一个包含dex字节码的APK文件。既然应用程序包含的仍然是dex字节码,而ART虚拟机需要的是本地机器码,这就必然要有一个翻译的过程。Android系统在应用程序安装时,通过dex2oat工具将应用的dex字节码翻译成本地机器码。
ART相关源代码:
OAT文件加载流程
1、读取oatdata符号地址获取Oat数据 startAddress。
2、读取oatlastword符号地址获取OAT数据 endAddress。
3、通过startAddress和endAddress定位Oat数据。
4、解析Oat数据。构建方法定位所需数据结构。
然后就可以调用加载OAT文件的代码了。
- Android ART虚拟机
- android ART虚拟机
- Android ART虚拟机
- Android的新虚拟机ART
- Android Dalvik虚拟机和ART虚拟机对比
- Android ART运行时与Dalvik虚拟机
- 到底什么是android虚拟机 (dalvik, art)
- Android虚拟机——Dalvik/ART
- android Dalvik与art虚拟机区别
- 跟核心虚拟机Dalvik说再见Android Runtime(ART)登场
- Android Dex vs ART 虚拟机运行效率提升
- Android的java虚拟机——从Dalvik到ART
- 用于Android ART虚拟机JNI调用的NativeBridge介绍
- Dalvik虚拟机和ART(Android RunTime)的区别
- Android Art 虚拟机 GC 机制之 java 部落的崛起
- Android开发之JAVA虚拟机、Dalvik虚拟机和ART虚拟机简介
- ART 和 Dalvik 虚拟机
- ART虚拟机参数说明
- 大型网站技术架构(1)
- IOS开发】@selector 调用方法,传递多参数。
- 标题
- JAVA——集合类
- iOS NSJSONSerialization使用
- Android ART虚拟机
- 百度地图开发(二)POI检索
- ListView,GridView的万能Adapter-------Android中的Adapter能玩出什么花样?
- 搭建ORACLE高可用 高性能 高扩展的 MMM_APE 架构
- Cocos2d-JS 数据持久化
- js如何获取当前月的天数
- Android okHttp上传单张或多张照片
- session_login
- Cocos2d-JS 基于HTTP网络通信