在zygote进程启动过程中会创建art虚拟机,那我们就看一下art虚拟机是怎么创建出来的。
用户空间的init进程起来之后,会根据.xxxrc 文件中的配置,把相关进程运行起来,通过fork()和execve()来创建和加载对应的进程,我们锁熟悉的zygote进程也是在这个时候被运行起来的,zygote进程的前身是app_process,到了后面才把这个进程的名字改成zygote,可执行程序为 /system/bin/app_process32 或 /system/bin/app_process64 。
frameworks/base/cmds/app_process/app_main.cpp
186 int main(int argc, char* const argv[])
187 {
...
197 AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv)); //创建虚拟机实例
...
306 if (zygote) {
307 runtime.start("com.android.internal.os.ZygoteInit", args, zygote);//初始化并启动虚拟机
308 } else if (className) {
309 runtime.start("com.android.internal.os.RuntimeInit", args, zygote); //参数zygote为true
310 } else {
311 fprintf(stderr, "Error: no class name or --zygote supplied.\n");
312 app_usage();
313 LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
314 return 10;
315 }
316 }
所以接下来我们重点跟踪runtime.start()的流程
class AppRuntime : public AndroidRuntime
35 {
36 public:
37 AppRuntime(char* argBlockStart, const size_t argBlockLength)
38 : AndroidRuntime(argBlockStart, argBlockLength)
39 , mClass(NULL)
40 {
41 }
42
43 void setClassNameAndArgs(const String8& className, int argc, char * const *argv) {
44 mClassName = className;
45 for (int i = 0; i < argc; ++i) {
46 mArgs.add(String8(argv[i]));
47 }
48 }
...
112 };
AppRuntime继承自AndroidRuntime,而AppRuntime 没有重写start()方法,所以跑到AndroidRuntime的start()里面。
frameworks/base/core/jni/AndroidRuntime.cpp
974 void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
975 {
976 ALOGD(">>>>>> START %s uid %d <<<<<<\n",
977 className != NULL ? className : "(unknown)", getuid());
...
1006 /* start the virtual machine */
1007 JniInvocation jni_invocation;
1008 jni_invocation.Init(NULL); //加载libart.so 并绑定里面对应的函数
1009 JNIEnv* env;
1010 if (startVm(&mJavaVM, &env, zygote) != 0) {
1011 return;
1012 }
...
1018 if (startReg(env) < 0) { //注册系统的jni函数
1019 ALOGE("Unable to register all android natives\n");
1020 return;
1021 }
...
1050 char* slashClassName = toSlashClassName(className);
1051 jclass startClass = env->FindClass(slashClassName);
1052 if (startClass == NULL) {
1053 ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
1054 /* keep going */
1055 } else {
1056 jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
1057 "([Ljava/lang/String;)V"); //查找java 类里面的main()函数
1058 if (startMeth == NULL) {
1059 ALOGE("JavaVM unable to find main() in '%s'\n",