System_Server是系統(tǒng)進(jìn)程击罪,而Zygote是Android java世界的基石。這兩位都在Android中扮演著十分重要的角色。有個(gè)很形象的比喻疏日,Zygote是爸爸盈滴,System_Server是大兒子涯肩,應(yīng)用是一堆小兒子就不說了。今天來說說這兩位仁兄的兩個(gè)特性:
1.System_Server使用捕捉異常的方式啟動(dòng)巢钓。
2.Zygote與System_Server共存亡病苗。
System_Server使用捕捉異常的方式啟動(dòng)
源文件:/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
入口是ZygoteInit的startSystemServer函數(shù),利用forkSystemServer函數(shù)產(chǎn)生了子進(jìn)程SystemServer,并且設(shè)置了SystemServer的pid症汹,uid硫朦,uidgroud等。但這時(shí)并沒有進(jìn)入SystemServer的main函數(shù)入口背镇,只是一個(gè)進(jìn)程跑起來了咬展,懂嗎。
private static boolean startSystemServer(String abiList, String socketName)
throws MethodAndArgsCaller, RuntimeException {
String args[] = {
"--setuid=1000", //SystemServer pid=1000,gid=1000,還設(shè)置了權(quán)限組
"--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的類名
};
...................
...................
//會(huì)利用linux的fork函數(shù)產(chǎn)生SystemServer子進(jìn)程
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);
}
//子進(jìn)程 SystemServer
handleSystemServerProcess(parsedArgs);
}
return true;
}
進(jìn)入handleSystemServerProcess函數(shù),這里的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
再進(jìn)入RuntimeInit類的zygoteInit函數(shù)
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
commonInit(); //初始化時(shí)區(qū)啥的
nativeZygoteInit(); //native的初始化啥的
applicationInit(targetSdkVersion, argv, classLoader); //參數(shù)argv是類名com.android.server.SystemServer
}
再進(jìn)入applicationInit函數(shù)
private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
invokeStaticMain(args.startClass, args.startArgs, classLoader);
}
再進(jìn)入invokeStaticMain函數(shù)瞒斩,在這里反射調(diào)用了SystemServer類破婆,并且獲取到main方法,但并沒有執(zhí)行胸囱,而是直接拋出一個(gè)異常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為空
}
那這個(gè)異常是由誰來捕捉呢旺矾?其實(shí)是在ZygoteInit的main函數(shù)捕捉的蔑鹦,如下圖
異常捕捉后,調(diào)用 caller.run();
這里caller是MethodAndArgsCaller類箕宙,是ZygoteInit的內(nèi)部類嚎朽。run方法會(huì)執(zhí)行SystemServer的main方法。從而完成SystemServer的啟動(dòng)柬帕。
public static class MethodAndArgsCaller extends Exception
implements Runnable {
public void run() {
mMethod.invoke(null, new Object[] { mArgs });
}
}
為什么SystemServer要采用捕捉異常的方式啟動(dòng)呢哟忍?源碼里面其實(shí)有注釋,應(yīng)該是啟動(dòng)一個(gè)新進(jìn)程時(shí)陷寝,用來清除之前的堆棧信息的锅很。
Zygote與System_Server共存亡
System_Server是一個(gè)很重要的進(jìn)程,如果掛了凤跑,Zygote必須重啟爆安,如果不重啟,手機(jī)就會(huì)進(jìn)入假死的狀態(tài),手機(jī)黑屏仔引,無聲扔仓,無法跟用戶交互等褐奥。
Zygote與System_Server共存亡是如何實(shí)現(xiàn)的呢?
入口:/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
Zygote調(diào)用forkSystemServer產(chǎn)生子進(jìn)程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
進(jìn)入forkSystemServer函數(shù)看看
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;
}
會(huì)jni進(jìn)入native函數(shù)
/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);
................................
}
繼續(xù)進(jìn)入ForkAndSpecializeCommon函數(shù)
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(); //注冊(cè)信號(hào)撬码,這里將關(guān)系共存亡
pid_t pid = fork();//fork產(chǎn)生子進(jìn)程systemserver
if (pid == 0) {
......... //子進(jìn)程的一些操作
} else if (pid > 0) {
// the parent process
}
return pid;
}
SetSigChldHandler用于注冊(cè)信號(hào),這里就是關(guān)系到Zygote與System_Server的共存亡版保。
static void SetSigChldHandler() {
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SigChldHandler; //信號(hào)處理函數(shù)
int err = sigaction(SIGCHLD, &sa, NULL);
if (err < 0) {
ALOGW("Error setting SIGCHLD handler: %s", strerror(errno));
}
}
SetSigChldHandler定義了信號(hào)處理函數(shù)SigChldHandler呜笑,當(dāng)信號(hào)SIGCHLD到來的時(shí)候,會(huì)進(jìn)入信號(hào)處理函數(shù)彻犁。
看看信號(hào)處理函數(shù)SigChldHandler叫胁,可以看到如果子進(jìn)程SystemServer掛了,Zygote就會(huì)自殺袖裕。從而完成了共存亡的光輝使命
static void SigChldHandler(int /*signal_number*/) {
pid_t pid;
int status;
//Zygote監(jiān)聽所有子進(jìn)程的存亡
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
//某一個(gè)子進(jìn)程掛了
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自殺
}
}
}
總結(jié)
1.System_Server采用拋出異常和捕捉異常的方式啟動(dòng),可以清除進(jìn)程的堆棧溉瓶,減少內(nèi)存占用急鳄。
2.System_Server與Zygote共存亡是通過父進(jìn)程調(diào)用waitpid的方式監(jiān)聽子進(jìn)程System_Server的死亡,當(dāng)子進(jìn)程死亡的時(shí)候堰酿,父進(jìn)程就自殺