学习ART之生成Runtime OAT文件

本文详细分析了Android ART虚拟机在启动过程中如何将DEX文件转化为OAT文件,包括JNI_CreateJavaVM、Runtime创建与初始化、ParsedOptions与Heap对象创建,以及ImageSpace的创建与初始化。在启动Zygote进程前,通过libart.so创建虚拟机,并初始化Runtime,创建堆空间,映射并打开OAT文件。
摘要由CSDN通过智能技术生成

从前一篇学习笔记——ART无缝对接Dalvik虚拟机中可以了解到Dalvik和ART这两种虚拟机机制的可执行文件存在着区别,ART对应的是OAT文件格式,而Dalvik则是dexy格式的文件,而且还知道将apk文件进行优化并转换为指定可执行文件的过程都是发生在应用程序安装的过程中,所不同的只是调用了不同的模块来进行转化而已。这次先来分析一下art虚拟机启动过程中生成oat文件的过程。

1.dex文件转化为oat文件

首先还是看一下讲dex转化成oat文件的代码,前两个参数就是输入的apk文件和输出的oat文件的描述符,后两个参数则是输入的文件路径和输出的文件路径,最后一个就是优化的标志:

static void run_dex2oat(int zip_fd, int oat_fd, const char* input_file_name,
    const char* output_file_name, const char* dexopt_flags)
{
    static const char* DEX2OAT_BIN = "/system/bin/dex2oat";
    static const int MAX_INT_LEN = 12;      // '-'+10dig+'\0' -OR- 0x+8dig
    char zip_fd_arg[strlen("--zip-fd=") + MAX_INT_LEN];
    char zip_location_arg[strlen("--zip-location=") + PKG_PATH_MAX];
    char oat_fd_arg[strlen("--oat-fd=") + MAX_INT_LEN];
    char oat_location_arg[strlen("--oat-name=") + PKG_PATH_MAX];

    sprintf(zip_fd_arg, "--zip-fd=%d", zip_fd);
    sprintf(zip_location_arg, "--zip-location=%s", input_file_name);
    sprintf(oat_fd_arg, "--oat-fd=%d", oat_fd);
    sprintf(oat_location_arg, "--oat-location=%s", output_file_name);

    ALOGV("Running %s in=%s out=%s\n", DEX2OAT_BIN, input_file_name, output_file_name);
    execl(DEX2OAT_BIN, DEX2OAT_BIN,
          zip_fd_arg, zip_location_arg,
          oat_fd_arg, oat_location_arg,
          (char*) NULL);
    ALOGE("execl(%s) failed: %s\n", DEX2OAT_BIN, strerror(errno));
}

这里将会执行的时在/system/bin/dex2oat来对apk文件中的class.dex进行优化。这个程序的源代码文件在art/dex2oat/dex2oat.cc文件中,本人水平所限,里面转化的代码有点难看懂,暂时就先放在一边了。

2.JNI_CreateJavaVM

在创建ART虚拟机的过程中会进行第一次的dex到oat文件的转化,这里就先分析一下这个过程以便对整个过程有个基础的了解。在之前分析过的JniInvocation::Init函数中有如下一段代码:

 if (!FindSymbol(reinterpret_cast<void**>(&JNI_GetDefaultJavaVMInitArgs_),
                 "JNI_GetDefaultJavaVMInitArgs")) { 
   return false; 
 }
 if (!FindSymbol(reinterpret_cast<void**>(&JNI_CreateJavaVM_),
                 "JNI_CreateJavaVM")) {
   return false;
 }      
 if (!FindSymbol(reinterpret_cast<void**>(&JNI_GetCreatedJavaVMs_),
                 "JNI_GetCreatedJavaVMs")) {
   return false;
 }
 return true;

这段代码就是获得创建虚拟机所必须的接口函数指针,而这里的接口则是根据文件中定义klibararyFallback字符串来获取的,kitkat中是libdvm.so,而在最新的5.0 lollipop的代码中可以看到变成了libart.so,也就是说art模式已经成为默认的虚拟机了:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值