在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", className);
1060 /* keep going */
1061 } else {
1062 env->CallStaticVoidMethod(startClass, startMeth, strArray); //执行main()函数
1068 }
1069 }
...
1072 ALOGD("Shutting down VM\n"); //如果java里面的main()跑完了,表示进程结束了,可以销毁虚拟机
1073 if (mJavaVM->DetachCurrentThread() != JNI_OK)
1074 ALOGW("Warning: unable to detach main thread\n");
1075 if (mJavaVM->DestroyJavaVM() != 0)
1076 ALOGW("Warning: VM did not shut down cleanly\n");
1077 }
加载libart.so过程分析
libnativehelper/ JniInvocation.cpp
static const char* kLibraryFallback = "libart.so";
bool JniInvocation::Init(const char* library) {
...
const int kDlopenFlags = RTLD_NOW | RTLD_NODELETE;
handle_ = dlopen(library, kDlopenFlags); //library 默认就是libart.so
if (handle_ == NULL) {
if (handle_ == NULL) {
if (strcmp(library, kLibraryFallback) == 0) {
// Nothing else to try.
ALOGE("Failed to dlopen %s: %s", library, dlerror());
return false;
}
...
library = kLibraryFallback;
handle_ = dlopen(library, kDlopenFlags); //如果上面是其他library并且加载失败,尝试加载libart.so
...
}
if (!FindSymbol(reinterpret_cast<void**>(&JNI_GetDefaultJavaVMInitArgs_),
"JNI_GetDefaultJavaVMInitArgs")) {//绑定library 中对应的函数
return false;
}
if (!FindSymbol(reinterpret_cast<void**>(&JNI_CreateJavaVM_),
"JNI_CreateJavaVM")) { //绑定library 中对应的函数
return false;
}
if (!FindSymbol(reinterpret_cast<void**>(&JNI_GetCreatedJavaVMs_),
"JNI_GetCreatedJavaVMs")) { //绑定library 中对应的函数
return false;
}
return true;
}
跑完JniInvocation的初始化函数,也就是加载好libart.so库后,开始跑startVM()。
frameworks/base/core/jni/AndroidRuntime.cpp
581 int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote)
582 {
583 JavaVMInitArgs initArgs;
584 char propBuf[PROPERTY_VALUE_MAX];
585 char stackTraceFileBuf[sizeof("-Xstacktracefile:")-1 + PROPERTY_VALUE_MAX];
586 char jniOptsBuf[sizeof("-Xjniopts:")-1 + PROPERTY_VALUE_MAX];
587 char heapstartsizeOptsBuf[sizeof("-Xms")-1 + PROPERTY_VALUE_MAX];
588 char heapsizeOptsBuf[sizeof("-Xmx")-1 + PROPERTY_VALUE_MAX];
589 char heapgrowthlimitOptsBuf[sizeof("-XX:HeapGrowthLimit=")-1 + PROPERTY_VALUE_MAX];
590 char heapminfreeOptsBuf[sizeof("-XX:HeapMinFree=")-1 + PROPERTY_VALUE_MAX];
591 char heapmaxfreeOptsBuf[sizeof("-XX:HeapMaxFree=")-1 + PROPERTY_VALUE_MAX];
592 char usejitOptsBuf[sizeof("-Xusejit:")-1 + PROPERTY_VALUE_MAX];
...前面设置了一大推参数,然后调用JNI_CreateJavaVM()创建虚拟机,并传入参数
933 if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
934 ALOGE("JNI_CreateJavaVM failed\n");
935 return -1;
936 }
937
938 return 0;
939 }
JNI_CreateJavaVM() 调用到JniInvocation中的JNI_CreateJavaVM()
libnativehelper/ JniInvocation.cpp
jint JniInvocation::JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {
return JNI_CreateJavaVM_(p_vm, p_env, vm_args);
}
JNI_CreateJavaVM_()指向的函数就是libart.so中的JNI_CreateJavaVM(),前面init()的时候进行了绑定(就是给JNI_CreateJavaVM_这个函数指针赋值)。
对应的函数定义在 art/runtime/java_vm_ext.cc
939 extern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {
940 ScopedTrace trace(__FUNCTION__);
941 const JavaVMInitArgs* args = static_cast<JavaVMInitArgs*>(vm_args);
...
946 RuntimeOptions options;
947 for (int i = 0; i < args->nOptions; ++i) {
948 JavaVMOption* option = &args->options[i];
//把参数转成键值对的形式
949 options.push_back(std::make_pair(std::string(option->optionString), option->extraInfo));
950 }
951 bool ignore_unrecognized = args->ignoreUnrecognized;
952 if (!Runtime::Create(options, ignore_unrecognized)) {//创建Runtime 实例
953 return JNI_ERR;
954 }
955
956 // Initialize native loader. This step makes sure we have
957 // everything set up before we start using JNI.
958 android::InitializeNativeLoader();
959
960 Runtime* runtime = Runtime::Current();
961 bool started = runtime->Start(); //启动虚拟机
962 if (!started) {
963 delete Thread::Current()->GetJniEnv();
964 delete runtime->GetJavaVM();
965 LOG(WARNING) << "CreateJavaVM failed";
966 return JNI_ERR;
967 }
968 //返回创建的JavaVM 和 JNIEnv
969 *p_env = Thread::Current()->GetJniEnv();
970 *p_vm = runtime->GetJavaVM();
971 return JNI_OK;
972 }
我们接下来看到Runtime::Create()做了什么事
art/runtime/runtime.cc
486 bool Runtime::Create(RuntimeArgumentMap&& runtime_options) {
487 // TODO: acquire a static mutex on Runtime to avoid racing.
488 if (Runtime::instance_ != nullptr) { //如果前面有创建过了,直接返回
489 return false;
490 }
491 instance_ = new Runtime; //真正创建出Runtime 实例,在一个进程中只有一个这样的实例
492 if (!instance_->Init(std::move(runtime_options))) { //调用init()函数进行初始化
493 // TODO: Currently deleting the instance will abort the runtime on destruction. Now This will
494 // leak memory, instead. Fix the destructor. b/19100793.
495 // delete instance_;
496 instance_ = nullptr;
497 return false;
498 }
499 return true;
500 }
501
502 bool Runtime::Create(const RuntimeOptions& raw_options, bool ignore_unrecognized) {
503 RuntimeArgumentMap runtime_options;
504 return ParseOptions(raw_options, ignore_unrecognized, &runtime_options) &&
505 Create(std::move(runtime_options));
506 }
所以接下来进入到init()函数里面932 bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) {
...
941 MemMap::Init(); //创建multimap
...
//这个十分重要,后面的博客在分析
1015 heap_ = new gc::Heap(runtime_options.GetOrDefault(Opt::MemoryInitialSize),
...
1046 if (!heap_->HasBootImageSpace() && !allow_dex_file_fallback_) {
1047 LOG(ERROR) << "Dex file fallback disabled, cannot continue without image.";
1048 return false;
1049 }
...
1083 BlockSignals();
1084 InitPlatformSignalHandlers();
...
1124 if (implicit_so_checks_) {
1125 new StackOverflowHandler(&fault_manager);
1126 }
1128 if (implicit_null_checks_) {
1129 new NullPointerHandler(&fault_manager);
1130 }
1132 if (kEnableJavaStackTraceHandler) {
1133 new JavaStackTraceHandler(&fault_manager);
1134 }
...
1138 java_vm_ = new JavaVMExt(this, runtime_options); //创建JavaVMExt实例,JavaVMExt继承自JavaVM
1139
1140 Thread::Startup();
...
1145 Thread* self = Thread::Attach("main", false, nullptr, false);//将JavaVM和当前线程绑定
...
1156 class_linker_ = new ClassLinker(intern_table_); //创建ClassLinker实例
1157 if (GetHeap()->HasBootImageSpace()) {
1158 std::string error_msg;
1159 bool result = class_linker_->InitFromBootImage(&error_msg);
...
1187 } else {
...
1223 }
1310 return true;
1311 }因为heap 的内容太多了,java 对象就分配在这个内存区域中,heap 又被划分为不同的区域,对应不同的内存管理策略。
继续看一下Thread::Attach()又做了那些事
art/runtime/thread.cc
732 Thread* Thread::Attach(const char* thread_name, bool as_daemon, jobject thread_group,
733 bool create_peer) {
734 Runtime* runtime = Runtime::Current(); //因为前面创建了Runtime,并且是一个全局的单例,所以通过Current()可以得到
735 if (runtime == nullptr) {
736 LOG(ERROR) << "Thread attaching to non-existent runtime: " << thread_name;
737 return nullptr;
738 }
739 Thread* self;
740 {
741 MutexLock mu(nullptr, *Locks::runtime_shutdown_lock_);
742 if (runtime->IsShuttingDownLocked()) {
743 LOG(WARNING) << "Thread attaching while runtime is shutting down: " << thread_name;
744 return nullptr;
745 } else {
746 Runtime::Current()->StartThreadBirth();
747 self = new Thread(as_daemon); //创建了一个Thread实例,这里的Thread是用来描述线程
748 bool init_success = self->Init(runtime->GetThreadList(), runtime->GetJavaVM()); //调用其init()函数
749 Runtime::Current()->EndThreadBirth();
750 if (!init_success) {
751 delete self;
752 return nullptr;
753 }
754 }
755 }
...
805 return self;
806 }
接下来看Init()里面做了什么
685 bool Thread::Init(ThreadList* thread_list, JavaVMExt* java_vm, JNIEnvExt* jni_env_ext) {
...
692 // Set pthread_self_ ahead of pthread_setspecific, that makes Thread::Current function, this
693 // avoids pthread_self_ ever being invalid when discovered from Thread::Current().
694 tlsPtr_.pthread_self = pthread_self();
...
698 if (!InitStackHwm()) {
699 return false;
700 }
701 InitCpu();
702 InitTlsEntryPoints(); //初始化外部库函数调用跳转表
703 RemoveSuspendTrigger();
704 InitCardTable();
705 InitTid();
706 interpreter::InitInterpreterTls(this); //初始化解释器调用跳转表
...
717 if (jni_env_ext != nullptr) {
718 DCHECK_EQ(jni_env_ext->vm, java_vm);
719 DCHECK_EQ(jni_env_ext->self, this);
720 tlsPtr_.jni_env = jni_env_ext;
721 } else {
722 tlsPtr_.jni_env = JNIEnvExt::Create(this, java_vm); //创建一个JNIEnvExt:实例,JNIEnvExt:继承自JNIEnv
723 if (tlsPtr_.jni_env == nullptr) {
724 return false;
725 }
726 }
728 thread_list->Register(this); //将thread 加入到thread_list中,thread_list在runtime中创建
729 return true;
730 }
在jni中我们经常用到JNIEnv 的相关函数,那么这些函数的定义在哪里呢?接下来看一下JNIEnvExt::create()做了什么。
art/runtime/jni_env_ext.c
48 JNIEnvExt* JNIEnvExt::Create(Thread* self_in, JavaVMExt* vm_in) {
49 std::unique_ptr<JNIEnvExt> ret(new JNIEnvExt(self_in, vm_in));
50 if (CheckLocalsValid(ret.get())) {
51 return ret.release();
52 }
53 return nullptr;
54 }
55 // JNIEnvExt构造函数如下
56 JNIEnvExt::JNIEnvExt(Thread* self_in, JavaVMExt* vm_in)
57 : self(self_in),
58 vm(vm_in),
59 local_ref_cookie(IRT_FIRST_SEGMENT),
60 locals(kLocalsInitial, kLocalsMax, kLocal, false),
61 check_jni(false),
62 runtime_deleted(false),
63 critical(0),
64 monitors("monitors", kMonitorsInitial, kMonitorsMax) {
65 functions = unchecked_functions = GetJniNativeInterface(); //返回一个函数指针结构体
66 if (vm->IsCheckJniEnabled()) {
67 SetCheckJniEnabled(true);
68 }
69 }
那么functions绑定了什么呢?art/runtime/jni_internal.cc
2731 const JNINativeInterface* GetJniNativeInterface() {
2732 return &gJniNativeInterface;
2733 }
2495 const JNINativeInterface gJniNativeInterface = {
2496 nullptr, // reserved0.
2497 nullptr, // reserved1.
2498 nullptr, // reserved2.
2499 nullptr, // reserved3.
2500 JNI::GetVersion,
2501 JNI::DefineClass,
2502 JNI::FindClass,
...
2637 JNI::CallStaticVoidMethod,
...
2715 JNI::GetJavaVM,
...
2729 };
所以我们在jni中调用JNIEnv 的函数对应的实现就在这里呀,比如FindClass()。
art/runtime/jni_internal.cc
338 static jclass FindClass(JNIEnv* env, const char* name) {
339 CHECK_NON_NULL_ARGUMENT(name);
340 Runtime* runtime = Runtime::Current();
341 ClassLinker* class_linker = runtime->GetClassLinker();
342 std::string descriptor(NormalizeJniClassDescriptor(name));
343 ScopedObjectAccess soa(env);
344 mirror::Class* c = nullptr;
345 if (runtime->IsStarted()) {
346 StackHandleScope<1> hs(soa.Self());
347 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(GetClassLoader(soa)));
348 c = class_linker->FindClass(soa.Self(), descriptor.c_str(), class_loader);
349 } else {
350 c = class_linker->FindSystemClass(soa.Self(), descriptor.c_str());
351 }
352 return soa.AddLocalReference<jclass>(c);
353 }到这里我们知道art虚拟机对应是Runtime 这个类,并且是一个单例模式,也就是一个进程(zygote进程或zygote子进程)中 只有一个Runtime实例。