android runtime 创建流程
来源:互联网 发布:微社区 源码 编辑:程序博客网 时间:2024/06/01 10:22
在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为true310 } 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 AndroidRuntime35 {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 have957 // 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 will494 // 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继承自JavaVM1139 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, this693 // 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:继承自JNIEnv723 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实例。
- android runtime 创建流程
- Android Surface创建流程
- Android runtime机制(二)zygote进程的启动流程
- android锁屏创建流程
- 理解Android进程创建流程
- 理解Android进程创建流程
- 理解Android进程创建流程
- 理解Android进程创建流程
- Android Activity对象创建流程
- 理解Android进程创建流程
- android进程创建流程(基于android 6.0)
- Android runtime
- Android Runtime
- Android Runtime
- Android runtime
- runtime 创建数据模型
- android 4.4 多媒体创建初始化流程
- Android Activity 创建&启动流程总结
- 线性表的顺序存储结构的常见操作(C语言代码实现)
- Noip2017提高组 退役记
- sdnu 1099
- zoj 2314 reactor cooling(无源汇有上下界可行流)
- Codejam之Alphabet Cake
- android runtime 创建流程
- 九九乘法表
- KindEditor使用技巧
- android发短信打电话
- 博客生涯开始!
- 求一个数的绝对值
- 28 May 15 在PHP中使用协程实现多任务调度
- Intellij Idea 码云教程
- 我在苏嵌学习的第一天