1Dalvik虚拟机的启动过程分析

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

Dalvik虚拟机的启动过程分析分类:Android2013-05-1300:5728821人阅读评论(18)收藏举报AndroidDalvikZygote在Android系统中,应用程序进程都是由Zygote进程孵化出来的,而Zygote进程是由Init进程启动的。Zygote进程在启动时会创建一个Dalvik虚拟机实例,每当它孵化一个新的应用程序进程时,都会将这个Dalvik虚拟机实例复制到新的应用程序进程里面去,从而使得每一个应用程序进程都有一个独立的Dalvik虚拟机实例。在本文中,我们就分析Dalvik虚拟机在Zygote进程中的启动过程。Zygote进程在启动的过程中,除了会创建一个Dalvik虚拟机实例之外,还会将Java运行时库加载到进程中来,以及注册一些Android核心类的JNI方法来前面创建的Dalvik虚拟机实例中去。注意,一个应用程序进程被Zygote进程孵化出来的时候,不仅会获得Zygote进程中的Dalvik虚拟机实例拷贝,还会与Zygote一起共享Java运行时库,这完全得益于Linux内核的进程创建机制(fork)。这种Zygote孵化机制的优点是不仅可以快速地启动一个应用程序进程,还可以节省整体的内存消耗,缺点是会影响开机速度,毕竟Zygote是在开机过程中启动的。不过,总体来说,是利大于弊的,毕竟整个系统只有一个Zygote进程,而可能有无数个应用程序进程,而且我们不会经常去关闭手机,大多数情况下只是让它进入休眠状态。从前面Android系统进程Zygote启动过程的源代码分析一文可以知道,Zygote进程在启动的过程中,会调用到AndroidRuntime类的成员函数start,接下来我们就这个函数开始分析Dalvik虚拟机启动相关的过程,如图1所示:图1Dalvik虚拟机的启动过程这个过程可以分为8个步骤,接下来我们就详细分析每一个步骤。Step1.AndroidRuntime.start[cpp]viewplaincopyprint?1.voidAndroidRuntime::start(constchar*className,constboolstartSystemServer)2.{3.......4.5./*startthevirtualmachine*/6.if(startVm(&mJavaVM,&env)!=0)7.gotobail;8.9./*10.*Registerandroidfunctions.11.*/12.if(startReg(env)0){13.LOGE(Unabletoregisterallandroidnatives\n);14.gotobail;15.}16.17.......18.19./*20.*StartVM.ThisthreadbecomesthemainthreadoftheVM,andwill21.*notreturnuntiltheVMexits.22.*/23.jclassstartClass;24.jmethodIDstartMeth;25.26.slashClassName=strdup(className);27.for(cp=slashClassName;*cp!='\0';cp++)28.if(*cp=='.')29.*cp='/';30.31.startClass=env-FindClass(slashClassName);32.if(startClass==NULL){33.LOGE(JavaVMunabletolocateclass'%s'\n,slashClassName);34./*keepgoing*/35.}else{36.startMeth=env-GetStaticMethodID(startClass,main,37.([Ljava/lang/String;)V);38.if(startMeth==NULL){39.LOGE(JavaVMunabletofindmain()in'%s'\n,className);40./*keepgoing*/41.}else{42.env-CallStaticVoidMethod(startClass,startMeth,strArray);43.......44.}45.}46.47.LOGD(ShuttingdownVM\n);48.if(mJavaVM-DetachCurrentThread()!=JNI_OK)49.LOGW(Warning:unabletodetachmainthread\n);50.if(mJavaVM-DestroyJavaVM()!=0)51.LOGW(Warning:VMdidnotshutdowncleanly\n);52.53.......54.}这个函数定义在文件frameworks/base/core/jni/AndroidRuntime.cpp中。AndroidRuntime类的成员函数start主要做了以下四件事情:1.调用成员函数startVm来创建一个Dalvik虚拟机实例,并且保存在成员变量mJavaVM中。2.调用成员函数startReg来注册一些Android核心类的JNI方法。3.调用参数className所描述的一个Java类的静态成员函数main,来作为Zygote进程的Java层入口。从前面Android系统进程Zygote启动过程的源代码分析一文可以知道,这个入口类就为com.android.internal.os.ZygoteInit。执行这一步的时候,Zygote进程中的Dalvik虚拟机实例就开始正式运作了。注意,在这一步中,也就是在com.android.internal.os.ZygoteInit类的静态成员函数main,会进行大量的Android核心类和系统资源文件预加载。其中,预加载的Android核心类可以参考frameworks/base/preloaded-classes这个文件,而预加载的系统资源就是包含在/system/framework/framework-res.apk中。4.从com.android.internal.os.ZygoteInit类的静态成员函数main返回来的时候,就说明Zygote进程准备要退出来了。在退出之前,会调用前面创建的Dalvik虚拟机实例的成员函数DetachCurrentThread和DestroyJavaVM。其中,前者用来将Zygote进程的主线程脱离前面创建的Dalvik虚拟机实例,后者是用来销毁前面创建的Dalvik虚拟机实例。接下来,我们就主要关注Dalvik虚拟机实例的创建过程,以及Android核心类JNI方法的注册过程,即AndroidRuntime类的成员函数startVm和startReg的实现。Step2.AndroidRuntime.startVm[cpp]viewplaincopyprint?1.intAndroidRuntime::startVm(JavaVM**pJavaVM,JNIEnv**pEnv)2.{3.intresult=-1;4.JavaVMInitArgsinitArgs;5.JavaVMOptionopt;6.......7.8.property_get(dalvik.vm.checkjni,propBuf,);9.if(strcmp(propBuf,true)==0){10.checkJni=true;11.}elseif(strcmp(propBuf,false)!=0){12./*propertyisneithertruenorfalse;fallbackonkernelparameter*/13.property_get(ro.kernel.android.checkjni,propBuf,);14.if(propBuf[0]=='1'){15.checkJni=true;16.}17.}18.......19.20.property_get(dalvik.vm.execution-mode,propBuf,);21.if(strcmp(propBuf,int:portable)==0){22.executionMode=kEMIntPortable;23.}elseif(strcmp(propBuf,int:fast)==0){24.executionMode=kEMIntFast;25.#ifdefined(WITH_JIT)26.}elseif(strcmp(propBuf,int:jit)==0){27.executionMode=kEMJitCompiler;28.#endif29.}30.31.property_get(dalvik.vm.stack-trace-file,stackTraceFileBuf,);32.......33.34.strcpy(heapsizeOptsBuf,-Xmx);35.property_get(dalvik.vm.heapsize,heapsizeOptsBuf+4,16m);36.//LOGI(Heapsize:%s,heapsizeOptsBuf);37.opt.optionString=heapsizeOptsBuf;38.mOptions.add(opt);39.......40.41.if(checkJni){42./*extendedJNIchecking*/43.opt.optionString=-Xcheck:jni;44.mOptions.add(opt);45.46.......47.}48.......49.50.if(executionMode==kEMIntPortable){51.opt.optionString=-Xint:portable;52.mOptions.add(opt);53.}elseif(executionMode==kEMIntFast){54.opt.optionString=-Xint:fast;55.mOptions.add(opt);56.#ifdefined(WITH_JIT)57.}elseif(executionMode==kEMJitCompiler){58.opt.optionString=-Xint:jit;59.mOptions.add(opt);60.#endif61.}62.......63.64.if(stackTraceFileBuf[0]!='\0'){65.staticconstchar*stfOptName=-Xstacktracefile:;66.67.stackTraceFile=(char*)malloc(strlen(stfOptName)+68.strlen(stackTraceFileBuf)+1);69.strcpy(stackTraceFile,stfOptName);70.strcat(stackTraceFile,stackTraceFileBuf);71.opt.optionString=stackTraceFile;72.mOptions.add(opt);73.}74.......75.76.initArgs.options=mOptions.editArray();77.initArgs.nOptions=mOptions.size();78.......79.80./*81.*InitializetheVM.82.*83.*TheJavaVM*isessentiallyper-process,andtheJNIEnv*isper-thread.84.*Ifthiscallsucceeds,theVMisready,andwecanstartissuing85.*JNIcalls.86.*/87.if(JNI_CreateJavaVM(pJavaVM,pEnv,&initArgs)0){88.LOGE(J

1 / 36
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功