Jimmy Chen

A Programmer

(原创)基于Android R之ART虚拟机的创建流程

  我们知道Android的底层是Linux系统,Android系统运行的APK都是包含的Java代码。要在Linux上运行Java代码,这里就会涉及Java虚拟机创建的过程,Android系统自5.1版本后使用的是ART虚拟机,所以这篇,研究ART虚拟机的创建过程,下面所有分析的代码都是基于Android11_R17进行分析。

  Zygote作为Android系统首个运行的Java进程,同时也是App进程的孵化器,可以稍微判断出ART虚拟机的创建会在zygote进程中进行。下面我们就从分析zygote进程出来,来看ART虚拟机的创建流程。zygote启动是在init.zygote64.rc文件中进行的,zygote启动的代码如下

  • service zygote 是rc文件的写法,表示这里启动的是一个service
  • /system/bin/app_process64 表示启动的二进制进程是/system/bin/app_process64,在手机端查看,/system/bin/app_process64是软连接到/system/bin/app_process的
  • 剩余部分是传递给app_process64的参数

上面一顿分析发现,如果想了解ART虚拟机的启动流程,那么就得看app_process的启动流程了

1. app_process源码分析

  app_process是由app_main.cpp编译而来,下面查看具体的实现,我们只关注ART虚拟机的创建部分,其余部分我们就略过

上述两个地方调用到AppRuntime,第一个是调用其构造,第二个就是调用其start,下面我们分别来看看这两处调用的内容

AppRuntime分析

  AppRuntime类的实现也是放在了app_main.cpp中,AppRuntime继承了父类AndroidRuntime,所以要分析AppRuntime的构造,我们同时还要关注其父类AndroidRuntime的构造方法

2.1 AppRutnime构造方法和AndroidRuntime构造方法

从上面的调用流程看,AppRuntime的实现很简单,只是做了graphics的初始化,还没有涉及到任何虚拟机创建的内容,因此我们可以推测,ART虚拟机实际的创建工作会在start方法中进行的。

2.2 runtime.start方法

  因为runtime实际的对象是AppRuntime,但是我们发现AppRuntime中是没有实现start方法的,因此我们直接查看AndroidRuntime类的start方法,

上面的代码中有注释表明,开始启动虚拟机。首先是构造JniInvocation对象,调用流程JniInvocation->JinInvocationCreate->JniInvocationImpl。到最后Impl类中,也只是将类中的成员进行初始化,没有进行特殊的函数调用,所以下面我们还是重点关注Init和startVM这两个方法

ART虚拟机启动的关键

3.1 JniInvocation的Init方法

  JniInvocation的Init方法也存在一个简单的调用链:JniInvocation::Init->JniInvocation::JinInvocationInit->JniInvocationImpl::Init,所以最后干活的还是JniInvocationImpl

Init方法主要的作用是对libart.so文件进行加载和解析,获取so库中的方法句柄留作后用

3.2 startVM方法

上面代码中最后调用JNI_CreateJavaVM来创建虚拟机,这里的JNI_CreateJavaVM是在JniInvocation.cpp中进行实现的,其中的实现很简单,就是调用JNI_CreateJavaVM_方法指针,在前一步Init的时候,我们已经从libart.so库中查找到这个方法的句斌,并将其赋值给JNI_CreateJavaVM_。这里绕了一下,但是最后还是会调用到libart.so库的方法。libart.so库中的JNI_CreateJavaVM是在java_vm_ext.cc这个文件中实现的

还差最后一小部分了,坚持看下去

3.2.1 Runtime::Create

ParseOptions方法目的简单,主要就是用来解析参数的,但是其内部的代码其实相当的复杂,就目前看其实不影响我们分析ART虚拟机的创建,所以我们就先跳过。有兴趣的伙伴可以去查看代码,接着我们分析Create方法的过程

上面重点还是看Runtime的Init方法,new Runtime主要还是进行变量初始化,不涉及过多的函数调用。Init方法是runtime创建过程中最为核心的函数了。ART虚拟机使用到的大多数模块都会在这里进行初始化。因为函数内容过多,我们只挑出重点的内容进行讲解

好了,这个方法内容真的是非常的多的,简单解释先到这里,JavaVmExt相关介绍,留到下一篇博主再做介绍。回到前面JNI_CreateJavaVM的地方,这里我们就算是介绍完Runtime::Create的相关内容了。接着我们看runtime->Start

3.2.2 Runtime::Start

OK,ART虚拟机启动的流程已简单介绍过,这篇不打算涉及特别多的细节,有涉及的一些细节计划在后面的文章再逐步展开。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注