详细分析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);
}
}
}