System_Server是系统进程,而Zygote是Android java世界的基石。这两位都在Android中扮演着十分重要的角色。有个很形象的比喻,Zygote是爸爸,System_Server是大儿子,应用是一堆小儿子就不说了。今天来说说这两位仁兄的两个特性:
1.System_Server使用捕捉异常的方式启动。
2.Zygote与System_Server共存亡。
System_Server使用捕捉异常的方式启动
源文件:/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
入口是ZygoteInit的startSystemServer函数,利用forkSystemServer函数产生了子进程SystemServer,并且设置了SystemServer的pid,uid,uidgroud等。但这时并没有进入SystemServer的main函数入口,只是一个进程跑起来了,懂吗。
private static boolean startSystemServer(String abiList, String socketName)
throws MethodAndArgsCaller, RuntimeException {
String args[] = {
"--setuid=1000", //SystemServer pid=1000,gid=1000,还设置了权限组
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"com.android.server.SystemServer", //SystemServer的类名
};
...................
...................
//会利用linux的fork函数产生SystemServer子进程
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
//子进程 SystemServer
handleSystemServerProcess(parsedArgs);
}
return true;
}
进入handleSystemServerProcess函数,这里的parsedArgs.remainingArgs就是类名com.android.server.SystemServer
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws ZygoteInit.MethodAndArgsCaller {
......
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
..................
}
}
/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
再进入RuntimeInit类的zygoteInit函数
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
commonInit(); //初始化时区啥的
nativeZygoteInit(); //native的初始化啥的
applicationInit(targetSdkVersion, argv, classLoader); //参数argv是类名com.android.server.SystemServer
}
再进入applicationInit函数
private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
invokeStaticMain(args.startClass, args.startArgs, classLoader);
}
再进入invokeStaticMain函数,在这里反射调用了SystemServer类,并且获取到main方法,但并没有执行,而是直接抛出一个异常throw new ZygoteInit.MethodAndArgsCaller。
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
Class> cl;
cl = Class.forName(className, true, classLoader);//反射获取SystemServer类
Method m;
m = cl.getMethod("main", new Class[] { String[].class }); //获取main方法
throw new ZygoteInit.MethodAndArgsCaller(m, argv); //抛出异常,argv为空
}
那这个异常是由谁来捕捉呢?其实是在ZygoteInit的main函数捕捉的,如下图
异常捕捉后,调用 caller.run();
这里caller是MethodAndArgsCaller类,是ZygoteInit的内部类。run方法会执行SystemServer的main方法。从而完成SystemServer的启动。
public static class MethodAndArgsCaller extends Exception
implements Runnable {
public void run() {
mMethod.invoke(null, new Object[] { mArgs });
}
}
为什么SystemServer要采用捕捉异常的方式启动呢?源码里面其实有注释,应该是启动一个新进程时,用来清除之前的堆栈信息的。
Zygote与System_Server共存亡
System_Server是一个很重要的进程,如果挂了,Zygote必须重启,如果不重启,手机就会进入假死的状态,手机黑屏,无声,无法跟用户交互等。
Zygote与System_Server共存亡是如何实现的呢?
入口:/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
Zygote调用forkSystemServer产生子进程SystemServer。
private static boolean startSystemServer(String abiList, String socketName)
throws MethodAndArgsCaller, RuntimeException {
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
}
/frameworks/base/core/java/com/android/internal/os/Zygote.java
进入forkSystemServer函数看看
public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
int pid = nativeForkSystemServer(
uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
return pid;
}
会jni进入native函数
/frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
static jint com_android_internal_os_Zygote_nativeForkSystemServer(
JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
jint debug_flags, jobjectArray rlimits, jlong permittedCapabilities,
jlong effectiveCapabilities) {
............................
pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
debug_flags, rlimits,
permittedCapabilities, effectiveCapabilities,
MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,
NULL, NULL);
................................
}
继续进入ForkAndSpecializeCommon函数
static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,
jint debug_flags, jobjectArray javaRlimits,
jlong permittedCapabilities, jlong effectiveCapabilities,
jint mount_external,
jstring java_se_info, jstring java_se_name,
bool is_system_server, jintArray fdsToClose,
jstring instructionSet, jstring dataDir) {
...............
...............
SetSigChldHandler(); //注册信号,这里将关系共存亡
pid_t pid = fork();//fork产生子进程systemserver
if (pid == 0) {
......... //子进程的一些操作
} else if (pid > 0) {
// the parent process
}
return pid;
}
SetSigChldHandler用于注册信号,这里就是关系到Zygote与System_Server的共存亡。
static void SetSigChldHandler() {
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SigChldHandler; //信号处理函数
int err = sigaction(SIGCHLD, &sa, NULL);
if (err < 0) {
ALOGW("Error setting SIGCHLD handler: %s", strerror(errno));
}
}
SetSigChldHandler定义了信号处理函数SigChldHandler,当信号SIGCHLD到来的时候,会进入信号处理函数。
看看信号处理函数SigChldHandler,可以看到如果子进程SystemServer挂了,Zygote就会自杀。从而完成了共存亡的光辉使命
static void SigChldHandler(int /*signal_number*/) {
pid_t pid;
int status;
//Zygote监听所有子进程的存亡
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
//某一个子进程挂了
if (WIFSIGNALED(status)) {
if (WTERMSIG(status) != SIGKILL) {
ALOGI("Process %d exited due to signal (%d)", pid, WTERMSIG(status));
}
}
//如果挂掉的是SystemServer
if (pid == gSystemServerPid) {
ALOGE("Exit zygote because system server (%d) has terminated", pid);
kill(getpid(), SIGKILL); //Zygote自杀
}
}
}
总结
1.System_Server采用抛出异常和捕捉异常的方式启动,可以清除进程的堆栈,减少内存占用。
2.System_Server与Zygote共存亡是通过父进程调用waitpid的方式监听子进程System_Server的死亡,当子进程死亡的时候,父进程就自杀