详细分析Android中实现Zygote的源码
概述
在Android系统中,所有的应用程序进程,以及用来运行系统关键服务的System进程都是由zygote进程负责创建的。因此,我们将它称为进程孵化器。zygote进程是通过复制自身的方式来创建System进程和应用程序进程的。由于zygote进程在启动时会在内部创建一个虚拟机实例,因此,通过复制zygote进程而得到的System进程和应用程序进程可以快速地在内部获得一个虚拟机实例拷贝。
zygote进程在启动完成之后,会马上将System进程启动起来,以便它可以将系统的关键服务启动起来。下面我们将介绍zygote进程的启动脚本,然后分析它和System进程的启动过程。
zygote分析
zygote进程的启动脚本如下:
servicezygote/system/bin/app_process-Xzygote/system/bin--zygote--start-system-server classmain socketzygotestream660rootsystem onrestartwrite/sys/android_power/request_statewake onrestartwrite/sys/power/stateon onrestartrestartmedia onrestartrestartnetd
在我之前的一篇博客中已经分析了init进程是如何启动service服务了,需要了解的同学可以参考这篇文章:Androidinit进程——解析配置文件
通过zygote服务的启动脚本,我们可以知道,zygote进程的实际是二进制文件app_process的调用,我们就从这个应用程序的main函数入手去分析一下zygote进程的启动过程,源码如下(/frameworks/base/cmds/app_process/app_main.cpp):
/** *将-Xzygote加入到JavaVMOption中,返回/system/bin参数指向的下标 */ intAndroidRuntime::addVmArguments(intargc,constchar*constargv[]) { inti; for(i=0;i<argc;i++){ if(argv[i][0]!='-'){ returni; } if(argv[i][1]=='-'&&argv[i][2]==0){ returni+1; } JavaVMOptionopt; memset(&opt,0,sizeof(opt)); opt.optionString=(char*)argv[i]; mOptions.add(opt); } returni; } intmain(intargc,char*constargv[]) { //zygotecallparameters ///system/bin/app_process-Xzygote/system/bin--zygote--start-system-server //TheseareglobalvariablesinProcessState.cpp mArgC=argc; mArgV=argv; mArgLen=0; for(inti=0;i<argc;i++){ mArgLen+=strlen(argv[i])+1; } //去除末尾的空格 mArgLen--; AppRuntimeruntime; constchar*argv0=argv[0]; //Processcommandlinearguments //ignoreargv[0] argc--; argv++; //Everythinguptp'--'orfirstnon'-'arggoestothevm inti=runtime.addVmArguments(argc,argv); //Parseruntimearguments.Stopatfirstunrecognizedoption. boolzygote=false; boolstartSystemServer=false; boolapplication=false; constchar*parentDir=NULL; constchar*niceName=NULL; constchar*className=NULL; while(i<argc){ constchar*arg=argv[i++]; if(!parentDir){ parentDir=arg; }elseif(strcmp(arg,"--zygote")==0){ zygote=true; niceName="zygote"; }elseif(strcmp(arg,"--start-system-server")==0){ startSystemServer=true; }elseif(strcmp(arg,"--application")==0){ application=true; }elseif(strncmp(arg,"--nice-name=",12)){ niceName=arg+12; }else{ className=arg; break; } } if(niceName&&*niceName){ setArgv0(argv0,niceName); set_process_name(niceName); } runtime.mParentDir=parentDir; if(zygote){ //进入到AppRuntime的start函数 runtime.start("com.android.internal.os.ZygoteInit", startSystemServer?"start-system-server":""); }elseif(className){ runtime.mClassName=className; runtime.mArgc=argc-i; runtime.mArgv=argv+i; runtime.start("com.android.internal.os.RuntimeInit",application?"application":"tool"); }else{ fprintf("stderr","Error:noclassnameor--zygotesupplied.\n"); app_usage(); LOG_ALWAYS_FATAL("app_process:noclassnameor--zygotesupplied"); return10; } }
在zygote的main函数中,通过AppRuntimeruntime代码创建了一个AppRuntime对象runtime,接下来Zygote进程就是通过它来进一步启动的。
init.rc中关于启动zygote命令中包含了–zygote参数,所以在if(strcmp(arg,“–zygote”)==0)判断的时候,会将niceName赋值为”zygote”,然后通过set_process_name(niceName)函数将当前进程的名称设置为zygote。这也是为什么调用的脚本为/system/bin/app_process,而进程名为zygote的原因。set_process_name函数的源码如下(/system/core/libcutils/process_name.c):
staticconstchar*process_name="unknown"; voidset_process_name(constchar*new_name) { if(new_name==NULL){ return; } intlen=strlen(new_name); char*copy=(char*)malloc(len+1); strcpy(copy,new_name); process_name=(constchar*)copy; }
从init.rc文件中关于zygote进程的配置参数可知,Zygote进程传递给应用程序app_process的启动参数arg还包含一个”–start-system-server”选项。因此,在调用AppRuntime对象runtime的成员函数start时,第二个参数为”start-system-server”,表示zygote进程启动完成之后,需要将system进程启动起来。
AppRuntime分析
AppRuntime类的成员函数start是从父类AndroidRuntime继承下来的,因此,接下来我们就继续分析AndroidRuntime类的成员函数start的实现,函数源码位置:/frameworks/base/core/jni/AndroidRuntime.cpp:
char*AndroidRuntime::toSlashClassName(constchar*className) { char*result=strdup(className); for(char*cp=result;*cp!='\0';cp++){ if(*cp=='.'){ *cp='/'; } } returnresult; } /** *StarttheAndroidruntime.Thisinvolvesstartingthevirtualmachine *andcallingthe"staticvoidmain(String[]args)"methodinttheclass *namedby"className". * *这两个参数的值分别为: *constchar*className="com.android.internal.os.ZygoteInit"; *constchar*options="start-system-server"; */ voidAndroidRuntime::start(constchar*className,constchar*options) { ALOGD("\n>>>>>AndroidRuntimeSTART%s<<<<<<\n", className!=NULL?className:"(unknown)"); /** *'startSystemServer==true'meansruntimeisobsoleteandnotrunfrom *init.rcanymore,soweprintoutthebootstarteventhere. */ if(strcmp(options,"start-system-server")==0){ constintLOG_BOOT_PROGRESS_START=3000; LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,ns2ms(systemTime(SYSTEM_TIME_MONOTONIC))); } //设置ANDROID_ROOT环境变量 constchar*rootDir=getenv("ANDROID_ROOT"); if(rootDir==NULL){ rootDir="/system"; if(!hasDir("/system")){ LOG_FATAL("Norootdirectoryspecified,and/androiddosenotexist."); return; } setenv("ANDROID_ROOT",rootDir,1); } JniInvocationjni_invocation; jni_invocation.Init(NULL); JNIEnv*env; //1.创建虚拟机 if(startVm(&mJavaVM,&env)!=0){ return; } onVmCreated(env); //2.注册JNI函数 if(startReg(env)<0){ ALOGE("Unabletoregisterallandroidnatives\n"); return; } jclassstringClass; jobjectArraystrArray; jstringclassNameStr; jstringoptionsStr; stringClass=env->FindClass("java/lang/String"); assert(stringClass!=NULL); //创建一个有两个元素的String数组,用Java代码表示为:String[]strArray=newString[2]; strArray=env->NewObjectArray(2,stringClass,NULL); assert(strArray!=NULL); classNameStr=env->NewStringUTF(className); assert(classNameStr!=NULL); //设置第一个元素为"com.android.internal.os.ZygoteInit" env->SetObjectArrayElement(strArray,0,classNameStr); optionsStr=env->NewStringUTF(options); //设置第二个元素为"start-system-server" env->SetObjectArrayElement(strArray,1,optionsStr); //将字符串"com.android.internal.os.ZygoteInit"转换为"com/android/internal/os/ZygoteInit" char*slashClassName=toSlashClassName(className); jclassstartClass=env->FindClass(slashClassName); if(startClass==NULL){ ALOGE("JavaVMunabletolocateclass'%s'\n",slashClassName); }else{ jmethodIDstartMeth=env->GetStaticMethodID(startClass,"main","([Ljava/lang/String;)V"); if(startMeth==NULL){ ALOGE("JavaVMunabletofindmain()in'%s\n'",className); }else{ //3. //通过JNI调用java函数,注意调用的是main函数,所属的类是"com.android.internal.os.ZygoteInit". //传递的参数是"com.android.internal.os.ZygoteInittrue" env->CallStaticVoidMethod(startClass,startMeth,strArray); } } free(slashClassName); ALOGD("ShuttingdownVM\n"); if(mJavaVM->DetachCurrentThread()!=JNI_OK){ ALOGW("Warning:unabletodetachmainthread\n"); } if(mJavaVM->DestoryJavaVM()!=0){ ALOGW("Warning:VMdidnotshutdowncleanly\n"); } }
上述代码有几处关键点,分别是:
- 创建虚拟机。
- 注册JNI函数。
- 进入Java世界。
接下来,我们分别分析这三个关键点。
创建虚拟机——startVm
startVm并没有特别之处,就是调用JNI的虚拟机创建函数,但是创建虚拟机时的一些参数却是在startVm中确定的,其源码如下:
#definePROPERTY_VALUE_MAX92 /** *StarttheDalvikVirtualMachine. * *Variousarguments,mostdeterminedbysystemproperties,arepassedin. *The"mOptions"vectorisupdated. * *Returns0onsuccess. */ intAndroidRuntime::startVm(JavaVM**pJavaVM,JNIENV**pEnv) { intresult=-1; JavaVMInitArgsinitArgs; JavaVMOptionopt; charpropBuf[PROPERTY_VALUE_MAX]; charstackTraceFileBuf[PROPERTY_VALUE_MAX]; chardexoptFlagsBuf[PROPERTY_VALUE_MAX]; charenableAssertBuf[sizeof("-ea:")-1+PROPERTY_VALUE_MAX]; charjniOptsBuf[sizeof("-Xjniopts:")-1+PROPERTY_VALUE_MAX]; charheapstartsizeOptsBuf[sizeof("-Xms")-1+PROPERTY_VALUE_MAX]; charheapsizeOptsBuf[sizeof("-Xms")-1+PROPERTY_VALUE_MAX]; charheapgrowthlimitOptsBuf[sizeof("-XX:HeapGrowthLimit=")-1+PROPERTY_VALUE_MAX]; charheapminfreeOptsBuf[sizeof("-XX:HeapMinFree=")-1+PROPERTY_VALUE_MAX]; charheapmaxfreeOptsBuf[sizeof("-XX:HeapMaxFree=")-1+PROPERTY_VALUE_MAX]; charheaptargetutilizationOptsBuf[sizeof("-XX:HeapTargetUtilization=")-1+PROPERTY_VALUE_MAX]; charjitcodecachesizeOptsBuf[sizeof("-Xjitcodecachesize:")-1+PROPERTY_VALUE_MAX]; charextraOptsBuf[PROPERTY_VALUE_MAX]; char*stackTraceFile=NULL; boolcheckJni=false; boolcheckDexSum=false; boollogStdio=false; enum{ KEMDefault, KEMIntPortable, KEMIntFast, KEMJitCompiler, }executionMode=KEMDefault; /** *这段代码是用了设置JNI_check选项的。JNI_check指的是Native层调用JNI函数时,系统所做的一些检查动作。 *这个选项虽然能增加可靠性,但是还有一些副作用: *1.因为检查工作比较耗时,所以会影响系统运行速度。 *2.有些检查工作比较耗时,一旦出错,整个进程会abort。 *所以,JNI_check选项一般只在eng版本设置。 */ property_get("dalvik.vm.checkjni",propBuf,""); if(strcmp(propBuf,"true")==0){ checkJni=true; }elseif(strcmp(propBuf,"false")!=0){ property_get("ro.kernel.android.checkjni",propBuf,""); if(propBuf[0]=='1'){ checkJni=true; } } property_get("dalvik.vm.execution-mode",propBuf,""); if(strcmp(propBuf,"int:portable")==0){ executionMode=KEMIntPortable; }elseif(strcmp(propBuf,"int:fast")==0){ executionMode=KEMIntFast; }elseif(strcmp(propBuf,"int:jit")==0){ executionMode=KEMJitCompiler; } //...省略大部分参数设置 /** *设置虚拟机的heapsize,默认为16m。绝大多数厂商都会在build.prop文件里修改这个属性,一般是256m。 *heapsize不能设置得过小,否则在操作大尺寸的图片时无法分配所需的内存。 */ strcpy(heapsizeOptsBuf,"-Xmx"); property_get("dalvik.vm.heapsize",heapsizeOptsBuf+4,"16m"); opt.optionString=heapsizeOptsBuf; mOptions.add(opt); //...... if(JNI_CreateJavaVM(pJavaVM,pEnv,&initArgs)<0){ ALOGE("JNI_CreateJavaVMfailed\n"); gotobail; } result=0; bail: free(stackTraceFile); returnresult; }
更多虚拟机参数的设置,我这里就不做特殊说明了,大家感兴趣可以自行google。(ps:因为我不太懂虚拟机这一块…)
注册JNI函数——startReg
上面讲了如何创建虚拟机,接下来需要给这个虚拟机注册一些JNI函数。正是因为后续的Java世界用到的一些函数是采用native方式实现的,所以才必须提前注册这些函数。
接下来,我们来看一下startReg函数的源码实现:
intAndroidRuntime::startReg(JNIEnv*env) { //设置Thread类的线程创建函数为javaCreateThreadEtc androidSetCreateThreadFunc((android_create_thread_fn)javaCreateThreadEtc); ALOGV("---registeringnativefunctions---\n"); env->PushLocalFrame(200); if(register_jni_procs(gRegJNI,NELEM(gRegJNI),env)<0){ env->PopLocalFrame(NULL); return-1; } env->PopLocalFrame(NULL); return0; }
关键是需要注册JNI函数,具体实现是由register_jni_procs函数实现的,我们来看一下这个函数的具体实现(/frameworks/base/core/jni/AndroidRuntime.cpp):
staticintregister_jni_procs(constRegJNIRecarray[],size_Tcount,JNIEnv*env) { for(size_ti=0;i<count;i++){ if(array[i].mProc(env)<0){ #ifndefNDEBUG ALOGD("------!!!%sfailedtoload\n",array[i].mName); #endif return-1; } } return0; }
通过源码,我们可以看到,register_jni_procs只是对array数组的mProc函数的封装,而array数组指向的是gRegJNI数组,我们来看一下这个数组的实现:
staticconstRegJNIRecgRegJNI[]={ REG_JNI(register_android_debug_JNITest), REG_JNI(register_com_android_internal_os_RuntimeInit), REG_JNI(register_android_os_SystemClock), REG_JNI(register_android_util_EventLog), REG_JNI(register_android_util_Log), REG_JNI(register_android_util_FloatMath), REG_JNI(register_android_text_format_Time), REG_JNI(register_android_content_AssetManager), REG_JNI(register_android_content_StringBlock), REG_JNI(register_android_content_XmlBlock), REG_JNI(register_android_emoji_EmojiFactory), REG_JNI(register_android_text_AndroidCharacter), REG_JNI(register_android_text_AndroidBidi), REG_JNI(register_android_view_InputDevice), REG_JNI(register_android_view_KeyCharacterMap), REG_JNI(register_android_os_Process), REG_JNI(register_android_os_SystemProperties), REG_JNI(register_android_os_Binder), REG_JNI(register_android_os_Parcel), REG_JNI(register_android_view_DisplayEventReceiver), REG_JNI(register_android_nio_utils), REG_JNI(register_android_graphics_Graphics), REG_JNI(register_android_view_GraphicBuffer), REG_JNI(register_android_view_GLES20DisplayList), REG_JNI(register_android_view_GLES20Canvas), REG_JNI(register_android_view_HardwareRenderer), REG_JNI(register_android_view_Surface), REG_JNI(register_android_view_SurfaceControl), REG_JNI(register_android_view_SurfaceSession), REG_JNI(register_android_view_TextureView), REG_JNI(register_com_google_android_gles_jni_EGLImpl), REG_JNI(register_com_google_android_gles_jni_GLImpl), REG_JNI(register_android_opengl_jni_EGL14), REG_JNI(register_android_opengl_jni_EGLExt), REG_JNI(register_android_opengl_jni_GLES10), REG_JNI(register_android_opengl_jni_GLES10Ext), REG_JNI(register_android_opengl_jni_GLES11), REG_JNI(register_android_opengl_jni_GLES11Ext), REG_JNI(register_android_opengl_jni_GLES20), REG_JNI(register_android_opengl_jni_GLES30), REG_JNI(register_android_graphics_Bitmap), REG_JNI(register_android_graphics_BitmapFactory), REG_JNI(register_android_graphics_BitmapRegionDecoder), REG_JNI(register_android_graphics_Camera), REG_JNI(register_android_graphics_CreateJavaOutputStreamAdaptor), REG_JNI(register_android_graphics_Canvas), REG_JNI(register_android_graphics_ColorFilter), REG_JNI(register_android_graphics_DrawFilter), REG_JNI(register_android_graphics_Interpolator), REG_JNI(register_android_graphics_LayerRasterizer), REG_JNI(register_android_graphics_MaskFilter), REG_JNI(register_android_graphics_Matrix), REG_JNI(register_android_graphics_Movie), REG_JNI(register_android_graphics_NinePatch), REG_JNI(register_android_graphics_Paint), REG_JNI(register_android_graphics_Path), REG_JNI(register_android_graphics_PathMeasure), REG_JNI(register_android_graphics_PathEffect), REG_JNI(register_android_graphics_Picture), REG_JNI(register_android_graphics_PorterDuff), REG_JNI(register_android_graphics_Rasterizer), REG_JNI(register_android_graphics_Region), REG_JNI(register_android_graphics_Shader), REG_JNI(register_android_graphics_SurfaceTexture), REG_JNI(register_android_graphics_Typeface), REG_JNI(register_android_graphics_Xfermode), REG_JNI(register_android_graphics_YuvImage), REG_JNI(register_android_graphics_pdf_PdfDocument), REG_JNI(register_android_database_CursorWindow), REG_JNI(register_android_database_SQLiteConnection), REG_JNI(register_android_database_SQLiteGlobal), REG_JNI(register_android_database_SQLiteDebug), REG_JNI(register_android_os_Debug), REG_JNI(register_android_os_FileObserver), REG_JNI(register_android_os_MessageQueue), REG_JNI(register_android_os_SELinux), REG_JNI(register_android_os_Trace), REG_JNI(register_android_os_UEventObserver), REG_JNI(register_android_net_LocalSocketImpl), REG_JNI(register_android_net_NetworkUtils), REG_JNI(register_android_net_TrafficStats), REG_JNI(register_android_net_wifi_WifiNative), REG_JNI(register_android_os_MemoryFile), REG_JNI(register_com_android_internal_os_ZygoteInit), REG_JNI(register_android_hardware_Camera), REG_JNI(register_android_hardware_camera2_CameraMetadata), REG_JNI(register_android_hardware_SensorManager), REG_JNI(register_android_hardware_SerialPort), REG_JNI(register_android_hardware_UsbDevice), REG_JNI(register_android_hardware_UsbDeviceConnection), REG_JNI(register_android_hardware_UsbRequest), REG_JNI(register_android_media_AudioRecord), REG_JNI(register_android_media_AudioSystem), REG_JNI(register_android_media_AudioTrack), REG_JNI(register_android_media_JetPlayer), REG_JNI(register_android_media_RemoteDisplay), REG_JNI(register_android_media_ToneGenerator), REG_JNI(register_android_opengl_classes), REG_JNI(register_android_server_NetworkManagementSocketTagger), REG_JNI(register_android_server_Watchdog), REG_JNI(register_android_ddm_DdmHandleNativeHeap), REG_JNI(register_android_backup_BackupDataInput), REG_JNI(register_android_backup_BackupDataOutput), REG_JNI(register_android_backup_FileBackupHelperBase), REG_JNI(register_android_backup_BackupHelperDispatcher), REG_JNI(register_android_app_backup_FullBackup), REG_JNI(register_android_app_ActivityThread), REG_JNI(register_android_app_NativeActivity), REG_JNI(register_android_view_InputChannel), REG_JNI(register_android_view_InputEventReceiver), REG_JNI(register_android_view_InputEventSender), REG_JNI(register_android_view_InputQueue), REG_JNI(register_android_view_KeyEvent), REG_JNI(register_android_view_MotionEvent), REG_JNI(register_android_view_PointerIcon), REG_JNI(register_android_view_VelocityTracker), REG_JNI(register_android_content_res_ObbScanner), REG_JNI(register_android_content_res_Configuration), REG_JNI(register_android_animation_PropertyValuesHolder), REG_JNI(register_com_android_internal_content_NativeLibraryHelper), REG_JNI(register_com_android_internal_net_NetworkStatsFactory), }; #ifdefNDEBUG #defineREG_JNI(name){name} structRegJNIRec{ int(*mProc)(JNIEnv*); }; #else #defineREG_JNI(name){name,#name} structRegJNIRec{ int(*mProc)(JNIEnv*); constchar*mName; }; #endif
可以看到,REG_JNI是一个宏,宏里面包括的就是那个参数为JNIEnv*,返回值为int的函数指针mProc,我们以register_android_debug_JNITest为例,源码位置为/frameworks/base/core/jni/android_debug_JNITest.cpp:
#defineNELEM(x)(sizeof(x)/sizeof(*(x))) intregister_android_debug_JNITest(JNIEnv*env) { returnjniRegisterNativeMethods(env,"android/debug/JNITest",gMethods,NELEM(gMethods)); }
可以看到,mProc其实就是为Java类注册JNI函数。
进入JAVA世界
可以看到CallStaticVoidMethod最终将调用com.android.internal.os.ZygoteInit的main函数,下面就来看一下这个Java世界的入口函数。源码位置:/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java,源码如下:
publicstaticvoidmain(Stringargv[]) { try{ SamplingProfilerIntegration.start(); //1.注册zygote用的socket registerZygoteSocket(); EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,SystemClock.uptimeMillis()); //2.预加载类和资源 preload(); EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,SystemClock.uptimeMillis()); SamplingProfilerIntegration.writeZygoteSnapshot(); //强制执行一次垃圾收集 gc(); Trace.setTracingEnabled(false); if(argv.length!=2){ thrownewRuntimeException(argv[0]+USAGE_STRING); } if(argv[1].equals("start-system-server")){ //3.启动system-server startSystemServer(); }elseif(!argv[1].equals("")){ thrownewRuntimeException(argv[0]+USAGE_STRING); } Log.i(TAG,"Acceptingcommandsocketconnections"); //4.进入请求应答模式 runSelectLoop(); closeServerSocket(); }catch(MethodAndArgsCallercaller){ caller.run(); }catch(RuntimeExceptionex){ Log.e(TAG,"Zygotediedwithexception",ex); closeServerSocket(); throwex; } }
上述代码中有5个重要的点,我已经通过标号标记出来了,接下来我们分别分析一下这5点函数的具体实现。
建立IPC通信服务端——registerZygoteSocket
zygote及系统中其他程序的通信没有使用Binder,而是采用了基于AF_UNIX类型的socket。registerZygoteSocket函数的使命正是建立这个Socket,实现代码如下:
privatestaticvoidregisterZygoteSocket() { if(sServerSocket==null){ intfileDesc; try{ Stringenv=System.getenv(ANDROID_SOCKET_ENV); fileDesc=Integer.parseInt(env); }catch(RuntimeExceptionex){ thrownewRuntimeException(ANDROID_SOCKET_ENV+"unsetorinvalid",ex); } try{ sServerSocket=newLocalServerSocket(createFileDescriptor(fileDesc)); }catch(IOExceptionex){ thrownewRuntimeException("Errorbindingtolocalsocket'"+fileDesc+"'",ex); } } } publicclassLocalServerSocket{ privatefinalLocalSocketImplimpl; privatefinalLocalSocketAddresslocalAddress; privatestaticfinalintLISTEN_BACKLOG=50; /** *CreateaLocalServerSocketfromafiledescriptorthat'salready *beencreatedandbound.listen()willbecalledimmediatelyonit. *Usedforcaseswherefiledescriptorsarepassedinviaenvironment *variables. */ publicLocalServerSocket(FileDescriptorfd)throwsIOException{ impl=newLocalSocketImpl(fd); impl.listen(LISTEN_BACKLOG); localAddress=impl.getSockAddress(); } }
registerZygoteSocket很简单,就是创建一个服务端的socket。
预加载类和资源——preload
我们先来看一下preload函数实现:
staticvoidpreload() { preloadClasses(); preloadResources(); preloadOpenGL(); }
preload函数里面分别调用了三个预加载函数,我们分别来分析一下这几个函数的实现。
首先是preloadClasses,函数实现如下:
privatestaticfinalintUNPRIVILEGED_UID=9999; privatestaticfinalintUNPRIVILEGED_GID=9999; privatestaticfinalintROOT_UID=0; privatestaticfinalintROOT_GID=0; privatestaticvoidpreloadClasses() { finalVMRuntimeruntime=VMRuntime.getRuntime(); InputStreamis=ClassLoader.getSystemClassLoader().getResourceAsStream(PRELOADED_CLASSES); if(is==null){ Log.e(TAG,"Couldn'tfind"+PRELOADED_CLASSES+"."); }else{ Log.i(TAG,"Preloadingclasses..."); longstartTime=SystemClock.uptimeMillis(); setEffectiveGroup(UNPRIVILEGED_GID); setEffectiveGroup(UNPRIVILEGED_UID); floatdefaultUtilization=runtime.getTargetHeapUtilization(); runtime.setTargetHeapUtilization(0.8f); System.gc(); runtime.runFinalizationSync(); Debug.startAllocCounting(); try{ //创建一个缓冲区为256字符的输入流 BufferedReaderbr=newBufferdReader(newInputStreamReader(is),256); intcount=0; Stringline; while((line=br.readLine())!=null){ //skipcommentsandblanklines. line=line.trim(); if(line.startsWith("#")||line.equals("")){ continue; } try{ if(false){ Log.v(TAG,"Preloading"+line+"..."); } Class.forName(line); count++; }catch(ClassNotFoundExceptione){ Log.w(TAG,"Classnotfoundforpreloading:"+line); }catch(UnsatisfiedLinkErrore){ Log.w(TAG,"Problempreloading"+line+":"+e); }catch(Throwablet){ Log.e(TAG,"Errorpreloading"+line+".",t); } } Log.i(TAG,"...preloaded"+count+"classesin"+(SystemClock.uptimeMillis()-startTime)+"ms."); }catch(IOExceptione){ Log.e(TAG,"Errorreading"+PRELOADED_CLASSES+".",e); }finally{ IoUtils.closeQuietly(is); runtime.setTargetHeapUtilization(defaultUtilization); runtime.preloadDexCaches(); Debug.stopAllocCounting(); setEffectiveUser(ROOT_UID); setEffectiveGroup(ROOT_GID); } } }
preloadClasses看起来很简单,但是实际上它有很多的类需要加载。可以查看一下/frameworks/base/preloaded-classes文件,这里面都是需要预加载的类。
接下来,分析一下preloadResources函数的源码:
privatestaticfinalbooleanPRELOAD_RESOURCES=true; privatestaticvoidpreloadResources() { finalVMRuntimeruntime=VMRuntime.getRuntime(); Debug.startAllocCounting(); try{ System.gc(); runtime.runFinalizationSync(); mResources=Resources.getSystem(); mResources.startPreloading(); if(PRELOAD_RESOURCES){ Log.i(TAG,"Preloadingresources..."); longstartTime=SystemClock.uptimeMillis(); TypedArrayar=mResources.obtainTypedArray(com.android.internal.R.array.preloaded_drawables); intN=preloadDrawables(runtime,ar); ar.recycle(); Log.i(TAG,"...preloaded"+N+"resourcesin"+(SystemClock.uptimeMillis()-startTime)+"ms."); startTime=SystemClock.uptimeMillis(); ar=mResources.obtainTypedArray(com.android.internal.R.array.preloaded_color_state_lists); N=preloadColorstateLists(runtime,ar); ar.recycle(); Log.i(TAG,"...preloaded"+N+"resourcesin"+(SystemClock.uptimeMillis()-startTime)+"ms."); } mResources.finishPreloading(); }catch(RuntimeExceptione){ Log.w(TAG,"Failurepreloadingresources",e); }finally{ Debug.stopAllocCounting(); } }
接下来,是预加载OpenGL。源码如下:
privatestaticvoidpreloadOpenGL() { if(!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING,false)){ EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY); } }
启动system_server
现在我们要分析第三个关键点:startSystemServer。这个函数会创建java世界中系统Service所驻留的进程system_server,该进程是framework的核心。如何system_server挂掉,会导致zygote自杀。我们来看一下startSystemServer()实现源码。
/** *Preparetheargumentsandforkforthesystemserverprocess. */ privatestaticbooleanstartSystemServer()throwsMethodAndArgsCaller,RuntimeException { longcapabilities=posixCapabilitiesAsBits( OsConstants.CAP_KILL, OsConstants.CAP_NET_ADMIN, OsConstants.CAP_NET_BIND_SERVICE, OsConstants.CAP_NET_BROADCAST, OsConstants.CAP_NET_RAW, OsConstants.CAP_SYS_MODULE, OsConstants.CAP_SYS_NICE, OsConstants.CAP_SYS_RESOURCE, OsConstants.CAP_SYS_TIME, OsConstants.CAP_SYS_TTY_CONFIG ); //设置参数 Stringargs[]={ "--setuid=1000", "--setgid=1000", "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1032,3001,3002,3003,3006,3007", "--capabilities="+capabilities+","+capabilities, "--runtime-init", "--nice-name=system_server",//进程名为system_server "com.android.server.SystemServer", }; ZygoteConnection.ArgumentsparsedArgs=null; intpid; try{ parsedArgs=newZygoteConnection.Arguments(args); ZygoteConnection.applyDebuggerSystemProperty(parsedArgs); ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs); /*Requesttoforkthesystemserverprocess*/ pid=Zygote.forkSystemServer( parsedArgs.uid,parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, null, parsedArgs.permittedCapabilities, parsedArgs.effectiveCapabilities ); }catch(IllegalArgumentExceptionex){ thrownewRuntimeException(ex); } /*Forchildprocess*/ if(pid==0){ handleSystemServerProcess(parsedArgs); } returntrue; }
有求必应之等待请求——runSelectLoop
zygote从startSystemServer返回后,将进入第四个关键的函数:runSelectLoop。我们来看一下这个函数的实现:
staticfinalintGC_LOOP_COUNT=10; privatestaticvoidrunSelectLoop()throwsMethodAndArgsCaller{ ArrayList<FileDescriptor>fds=newArrayList<FileDescriptor>(); ArrayList<ZygoteConnection>peers=newArrayList<ZygoteConnection>(); FileDescriptor[]fdArray=newFileDescriptor[4]; fds.add(sServerSocket.getFileDescriptor()); peers.add(null); intloopCount=GC_LOOP_COUNT; while(true){ intindex; if(loopCount<=0){ gc(); loopCount=GC_LOOP_COUNT; }else{ loopCount--; } try{ fdArray=fds.toArray(fdArray); index=selectReadable(fdArray); }catch(IOExceptionex){ thrownewRuntimeException("Errorinselect()",ex); } if(index<0){ thrownewRuntimeException("Errorinselect()"); }elseif(index==0){ ZygoteConnectionnewPeer=acceptCommandPeer(); peers.add(newPeer); } } }