1 . zygote进程是什么?
zygote 进程是Android系统的一个主要特征, 它通过COW 方式运行在内存中的进程实现最大程度的复用, 并通过库共享有效降低内存的使用量(foot print).
2. zygote 进程的创建过程
(1) 如何传递参数?
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
-Xzygote : 传递给虚拟机的选项。在dalvik/vm/Init.cpp
} else if (strcmp(argv[i], "-Xzygote") == 0) { 1046 <strong> gDvm.zygote = true;</strong>
--start-system-server: 传递给生成的类,用于启动系统服务器。
(2) 在启用虚拟机时,会创建一些虚拟机选项。
int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv)
property_get("dalvik.vm.checkjni", propBuf, ""); if (strcmp(propBuf, "true") == 0) { checkJni = true; } else if (strcmp(propBuf, "false") != 0) { /* property is neither true nor false; fall back on kernel parameter */ property_get("ro.kernel.android.checkjni", propBuf, ""); if (propBuf[0] == '1') { checkJni = true; } }
/* * The default starting and maximum size of the heap. Larger * values should be specified in a product property override. */ strcpy(heapstartsizeOptsBuf, "-Xms"); property_get("dalvik.vm.heapstartsize", heapstartsizeOptsBuf+4, "4m"); opt.optionString = heapstartsizeOptsBuf; mOptions.add(opt); strcpy(heapsizeOptsBuf, "-Xmx"); property_get("dalvik.vm.heapsize", heapsizeOptsBuf+4, "16m"); opt.optionString = heapsizeOptsBuf; mOptions.add(opt);
ALOGD("CheckJNI is %s\n", checkJni ? "ON" : "OFF"); if (checkJni) { /* extended JNI checking */ opt.optionString = "-Xcheck:jni"; mOptions.add(opt); /* set a cap on JNI global references */ opt.optionString = "-Xjnigreflimit:2000"; mOptions.add(opt); /* with -Xcheck:jni, this provides a JNI function call trace */ //opt.optionString = "-verbose:jni"; //mOptions.add(opt); }
if (<strong>JNI_CreateJavaVM</strong>(pJavaVM, pEnv, &initArgs) < 0) { ALOGE("JNI_CreateJavaVM failed\n"); goto bail; }
2. 创建 system_server进程:
有一个疑问, 多个参数是如何传递的呢? 在zygote.java
public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags, int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) { preFork(); int pid = nativeForkSystemServer( uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities); postFork(); return pid; } native public static int nativeForkSystemServer(int uid, int gid, int[] gids, int debugFlags, int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);
在 JNI层:
/* * native public static int nativeForkSystemServer(int uid, int gid, * int[] gids, int debugFlags, int[][] rlimits, * long permittedCapabilities, long effectiveCapabilities); */ static void Dalvik_dalvik_system_Zygote_forkSystemServer( <strong>const u4* args</strong>, JValue* pResult) { pid_t pid; pid = forkAndSpecializeCommon(args, true);
zygote进程会check system_server进程是否创建成功,WNOHANG option使得 如果没有system_server进程退出,那么waitepid会立即返回;
static void Dalvik_dalvik_system_Zygote_forkSystemServer( const u4* args, JValue* pResult) { pid_t pid; pid = forkAndSpecializeCommon(args, true); /* The zygote process checks whether the child process has died or not. */ if (pid > 0) { int status; ALOGI("System server process %d has been created", pid); gDvm.systemServerPid = pid; /* There is a slight window that the system server process has crashed * but it went unnoticed because we haven't published its pid yet. So * we recheck here just to make sure that all is well. */ if (waitpid(pid, &status, <strong>WNOHANG)</strong> == pid) { ALOGE("System server process %d has died. Restarting Zygote!", pid); kill(getpid(), SIGKILL); //自杀 } } RETURN_INT(pid); }
* Utility routine to fork zygote and specialize the child process.
static int setSELinuxContext(uid_t uid, bool isSystemServer, const char *seInfo, const char *niceName) { #ifdef HAVE_ANDROID_OS return selinux_android_setcontext(uid, isSystemServer, seInfo, niceName); #else return 0; #endif } #endif /* * Utility routine to fork zygote and specialize the child process. */ static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer) { pid_t pid; uid_t uid = (uid_t) args[0]; gid_t gid = (gid_t) args[1]; ArrayObject* gids = (ArrayObject *)args[2]; u4 debugFlags = args[3]; ArrayObject *rlimits = (ArrayObject *)args[4]; u4 mountMode = MOUNT_EXTERNAL_NONE; int64_t permittedCapabilities, effectiveCapabilities; #ifdef HAVE_SELINUX char *seInfo = NULL; char *niceName = NULL; #endif if (isSystemServer) { /* * Don't use GET_ARG_LONG here for now. gcc is generating code * that uses register d8 as a temporary, and that's coming out * scrambled in the child process. b/3138621 */ //permittedCapabilities = GET_ARG_LONG(args, 5); //effectiveCapabilities = GET_ARG_LONG(args, 7); permittedCapabilities = args[5] | (int64_t) args[6] << 32; effectiveCapabilities = args[7] | (int64_t) args[8] << 32; } else { mountMode = args[5]; permittedCapabilities = effectiveCapabilities = 0; #ifdef HAVE_SELINUX StringObject* seInfoObj = (StringObject*)args[6]; if (seInfoObj) { seInfo = dvmCreateCstrFromString(seInfoObj); if (!seInfo) { ALOGE("seInfo dvmCreateCstrFromString failed"); dvmAbort(); } } StringObject* niceNameObj = (StringObject*)args[7]; if (niceNameObj) { niceName = dvmCreateCstrFromString(niceNameObj); if (!niceName) { ALOGE("niceName dvmCreateCstrFromString failed"); dvmAbort(); } } #endif } if (!gDvm.zygote) { dvmThrowIllegalStateException( "VM instance not started with -Xzygote"); return -1; } if (!dvmGcPreZygoteFork()) { ALOGE("pre-fork heap failed"); dvmAbort(); } <strong>setSignalHandler();</strong> ... ... }
自进程创建成功后,那么在system_server中,都做了些什么操作的呢?
/** * Finish remaining work for the newly forked system server process. */ private static void handleSystemServerProcess( ZygoteConnection.Arguments parsedArgs) throws ZygoteInit.MethodAndArgsCaller { closeServerSocket(); // set umask to 0077 so new files and directories will default to owner-only permissions. Libcore.os.umask(S_IRWXG | S_IRWXO); if (parsedArgs.niceName != null) { Process.setArgV0(parsedArgs.niceName); } if (parsedArgs.invokeWith != null) { WrapperInit.execApplication(parsedArgs.invokeWith, parsedArgs.niceName, parsedArgs.targetSdkVersion, null, parsedArgs.remainingArgs); } else { /* * Pass the remaining arguments to SystemServer. */ RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs); } /* should never reach here */ }
// set umask to 0077 so new files and directories will default to owner-only permissions. <strong> Libcore.os.umask(S_IRWXG | S_IRWXO);</strong>
package libcore.io; public final class Libcore { private Libcore() { } <strong>public static Os os = new BlockGuardOs(new Posix());</strong> }
在java 中,可以对成员变量直接初始化。 这一点与c++ 不同。
会调用 Posix.java , 通过jni 调用
Posix 实现了OS接口:
public final class Posix implements Os { Posix() { }
public native int umask(int mask);