摘要:注此次分析以源碼為例。孵化器受精卵名字是受精卵,其實(shí)就是幫助或其他進(jìn)程啟動(dòng)的一個(gè)玩意兒。啟動(dòng)系統(tǒng)服務(wù)是系統(tǒng)的大核心之一,和一并重要,專管所有的系統(tǒng)服務(wù)。每個(gè)進(jìn)程都走這一步這個(gè)分支到此先不往下跟蹤了,和啟動(dòng)的過(guò)程關(guān)系不大了。
注:此次分析以6.0源碼為例。
android系統(tǒng)是從linux改過(guò)來(lái)的,因此這里從init進(jìn)程開始進(jìn)行分析。
init初始化過(guò)程讓我們進(jìn)入init.cpp來(lái)看看,首先看main:
/Volumes/aosp/WORKING_DIRECTORY/system/core/init/init.cpp
int main(int argc, char** argv) { // 判斷是否是啟動(dòng)的第一階段,根據(jù)參數(shù)來(lái)判斷 bool is_first_stage = (argc == 1) || (strcmp(argv[1], "--second-stage") != 0); if (is_first_stage) { // 如果是第一階段 mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"); // 掛載tmpfs文件系統(tǒng)(快速的臨時(shí)文件系統(tǒng),建立在內(nèi)存上,不可持久) mkdir("/dev/pts", 0755); mkdir("/dev/socket", 0755); mount("devpts", "/dev/pts", "devpts", 0, NULL); // 掛載devpts文件系統(tǒng) mount("proc", "/proc", "proc", 0, NULL); // 掛載proc文件系統(tǒng) mount("sysfs", "/sys", "sysfs", 0, NULL); // 掛載sysfs文件系統(tǒng)(設(shè)備結(jié)構(gòu)) } ...... if (!is_first_stage) { // Indicate that booting is in progress to background fw loaders, etc. close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000)); property_init(); // 初始化屬性域 system/core/init/Property_service.cpp // If arguments are passed both on the command line and in DT, // properties set in DT always have priority over the command-line ones. process_kernel_dt(); process_kernel_cmdline(); // Propogate the kernel variables to internal variables // used by init as well as the current required properties. export_kernel_boot_props(); } ...... if (is_first_stage) { if (restorecon("/init") == -1) { ERROR("restorecon failed: %s ", strerror(errno)); security_failure(); } // 重入main,進(jìn)入第二階段 char* path = argv[0]; char* args[] = { path, const_cast("--second-stage"), nullptr }; if (execv(path, args) == -1) { ERROR("execv("%s") failed: %s ", path, strerror(errno)); security_failure(); } } ...... epoll_fd = epoll_create1(EPOLL_CLOEXEC); // 創(chuàng)建epoll ...... signal_handler_init(); // 初始化子進(jìn)程處理器,防止僵尸進(jìn)程。這里使用信號(hào)來(lái)監(jiān)控子進(jìn)程退出 ...... start_property_service(); // 啟動(dòng)屬性服務(wù) init_parse_config_file("/init.rc"); // 解析init.rc文件 ...... // 不斷監(jiān)聽(tīng)執(zhí)行上面rc解析出來(lái)的指令 while (true) { if (!waiting_for_exec) { execute_one_command(); // 執(zhí)行指令 restart_processes(); } int timeout = -1; if (process_needs_restart) { timeout = (process_needs_restart - gettime()) * 1000; if (timeout < 0) timeout = 0; } if (!action_queue_empty() || cur_action) { timeout = 0; } bootchart_sample(&timeout); epoll_event ev; int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1, timeout)); if (nr == -1) { ERROR("epoll_wait failed: %s ", strerror(errno)); } else if (nr == 1) { ((void (*)()) ev.data.ptr)(); } } }
整個(gè)init階段分為2個(gè)階段,第一階段主要是掛載文件系統(tǒng)等工作,然后這里會(huì)有個(gè)重入main的動(dòng)作,這次重入后開始執(zhí)行第二階段,第二階段主要處理各種屬性域,epoll,啟動(dòng)屬性服務(wù),防止僵尸進(jìn)程等瑣碎的事情。然后開始執(zhí)行init.rc中配置的指令。下面看看這個(gè)rc文件:
/Volumes/aosp/WORKING_DIRECTORY/system/core/rootdir/init.rc
import /init.environ.rc import /init.usb.rc import /init.${ro.hardware}.rc import /init.usb.configfs.rc import /init.${ro.zygote}.rc import /init.trace.rc
可以看到這里引用了/init.${ro.zygote}.rc,對(duì)應(yīng)的是類似init.zygote64.rc這些文件:
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server class main socket zygote stream 660 root system onrestart write /sys/android_power/request_state wake onrestart write /sys/power/state on onrestart restart media onrestart restart netd writepid /dev/cpuset/foreground/tasks
這里實(shí)際執(zhí)行的是app_main.cpp的main:
/Volumes/aosp/WORKING_DIRECTORY/frameworks/base/cmds/app_process/app_main.cpp
// 根據(jù)參數(shù)設(shè)置類名 while (i < argc) { const char* arg = argv[i++]; if (strcmp(arg, "--zygote") == 0) { zygote = true; niceName = ZYGOTE_NICE_NAME; } else if (strcmp(arg, "--start-system-server") == 0) { startSystemServer = true; } else if (strcmp(arg, "--application") == 0) { application = true; } else if (strncmp(arg, "--nice-name=", 12) == 0) { niceName.setTo(arg + 12); } else if (strncmp(arg, "--", 2) != 0) { className.setTo(arg); break; } else { --i; break; } } ...... if (zygote) { // 這里執(zhí)行到ZygoteInit類中 runtime.start("com.android.internal.os.ZygoteInit", args, zygote); } else if (className) { runtime.start("com.android.internal.os.RuntimeInit", args, zygote); } else { fprintf(stderr, "Error: no class name or --zygote supplied. "); app_usage(); LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied."); return 10; }
根據(jù)參數(shù)判斷,如果是zygote則在后面執(zhí)行runtime.start,給定的參數(shù)是ZygoteInit這個(gè)類。
runtime實(shí)際執(zhí)行的是AndroidRuntime.cpp中的代碼:
/Volumes/aosp/WORKING_DIRECTORY/frameworks/base/core/jni
void AndroidRuntime::start(const char* className, const Vector& options, bool zygote) ...... jmethodID startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V"); if (startMeth == NULL) { ALOGE("JavaVM unable to find main() in "%s" ", className); /* keep going */ } else { env->CallStaticVoidMethod(startClass, startMeth, strArray); #if 0 if (env->ExceptionCheck()) threadExitUncaughtException(env); #endif } ...... }
實(shí)際執(zhí)行的就是env->CallStaticVoidMethod(startClass, startMeth, strArray);這句話,調(diào)用的就是ZygoteInit.java中的main。至此,從init進(jìn)入到Zygote中了。
Zygote孵化器(受精卵)zygote名字是受精卵,其實(shí)就是幫助app或其他進(jìn)程啟動(dòng)的一個(gè)玩意兒。內(nèi)部就是走的fork分裂出一個(gè)進(jìn)程來(lái)。
/Volumes/aosp/WORKING_DIRECTORY/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) { try { ...... for (int i = 1; i < argv.length; i++) { if ("start-system-server".equals(argv[i])) { // 這里傳遞的就是這個(gè) startSystemServer = true; } else if (argv[i].startsWith(ABI_LIST_ARG)) { abiList = argv[i].substring(ABI_LIST_ARG.length()); } else if (argv[i].startsWith(SOCKET_NAME_ARG)) { socketName = argv[i].substring(SOCKET_NAME_ARG.length()); } else { throw new RuntimeException("Unknown command line argument: " + argv[i]); } } ...... registerZygoteSocket(socketName); // 注冊(cè)并啟動(dòng)socket服務(wù)端,為zygote ...... if (startSystemServer) { startSystemServer(abiList, socketName); // 啟動(dòng)systemserver } ...... runSelectLoop(abiList); // 進(jìn)入looper,等待啟動(dòng)app的請(qǐng)求 } // 注意這里,是個(gè)關(guān)鍵點(diǎn)。異常發(fā)生的時(shí)候調(diào)用了MethodAndArgsCaller這個(gè)runnable的run catch (MethodAndArgsCaller caller) { caller.run(); } }
基本就這些了,總結(jié)一下:
1.zygote使用本地socket進(jìn)行通訊,并接受請(qǐng)求從而進(jìn)行分裂的處理;
2.啟動(dòng)systemserver這個(gè)大戶;
3.zygote永不退出,生命周期在系統(tǒng)啟動(dòng)一直到結(jié)束,并且從runSelectLoop開始徹底成為孵化器服務(wù)進(jìn)程;
4.一旦發(fā)生MethodAndArgsCaller caller異常,調(diào)用MethodAndArgsCaller的call處理,后面我們會(huì)說(shuō)到這個(gè);
按照順序,我們首先來(lái)看看startSystemServer。
1. startSystemServer啟動(dòng)系統(tǒng)服務(wù)SystemServer是系統(tǒng)的2大核心之一,和Zygote一并重要,專管所有的系統(tǒng)服務(wù)。需要多帶帶開篇來(lái)闡述。這里我們只說(shuō)啟動(dòng)的過(guò)程。
private static boolean startSystemServer(String abiList, String socketName) throws MethodAndArgsCaller, RuntimeException { ...... // fork SystemServer進(jìn)程 pid = Zygote.forkSystemServer( parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, null, parsedArgs.permittedCapabilities, parsedArgs.effectiveCapabilities); ...... // 如果是子進(jìn)程,就是SystemServer本身,執(zhí)行 if (pid == 0) { if (hasSecondZygote(abiList)) { waitForSecondaryZygote(socketName); } // 如果是子進(jìn)程,即systemserver,調(diào)用handleSystemServerProcess進(jìn)行后面的收尾工作 handleSystemServerProcess(parsedArgs); } }
好吧,我們繼續(xù)看handleSystemServerProcess:
private static void handleSystemServerProcess( ZygoteConnection.Arguments parsedArgs) throws ZygoteInit.MethodAndArgsCaller { ...... RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl); ...... }
其實(shí)重要的就這一句話調(diào)用。繼續(xù)往下跟蹤:
/Volumes/aosp/WORKING_DIRECTORY/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { ...... // 常規(guī)初始化,設(shè)置跟蹤,設(shè)置網(wǎng)絡(luò)代理 commonInit(); // AndroidRuntime.cpp c層函數(shù) nativeZygoteInit(); // 應(yīng)用程序初始化 applicationInit(targetSdkVersion, argv, classLoader); }
基本上就是上面這3個(gè)調(diào)用最重要,我們依次看下:
/Volumes/aosp/WORKING_DIRECTORY/frameworks/base/core/jni/AndroidRuntime.cpp
static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz) { gCurRuntime->onZygoteInit(); }
看到了吧,回到了app_main.cpp AppRuntime的onZygoteInit中:
virtual void onZygoteInit() { spproc = ProcessState::self(); ALOGV("App process: starting thread pool. "); // 啟動(dòng)線程池,用于與binder通訊。每個(gè)進(jìn)程都走這一步 proc->startThreadPool(); }
這個(gè)分支到此先不往下跟蹤了,和啟動(dòng)的過(guò)程關(guān)系不大了。
下面我們回到RuntimeInit.java看下applicationInit:
private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { // 設(shè)置關(guān)閉引用程序是是否調(diào)用AppRuntime.onExit(),默認(rèn)調(diào)用 nativeSetExitWithoutCleanup(true); ...... // 傳遞參數(shù),并調(diào)用類的main方法 invokeStaticMain(args.startClass, args.startArgs, classLoader); }
關(guān)鍵方法是invokeStaticMain,執(zhí)行類的main方法,這個(gè)類在前面的startSystemServer里面有參數(shù)傳遞,具體是這樣的:
String args[] = { "--setuid=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", };
所以這個(gè)類就是SystemServer,調(diào)用的就是他的main方法。
下面看看invokeStaticMain內(nèi)部:
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { Class> cl; // 通過(guò)反射獲取類名 try { cl = Class.forName(className, true, classLoader); } catch (ClassNotFoundException ex) { throw new RuntimeException( "Missing class when invoking static main " + className, ex); } // 獲取該類的main方法 Method m; try { m = cl.getMethod("main", new Class[] { String[].class }); } catch (NoSuchMethodException ex) { throw new RuntimeException( "Missing static main on " + className, ex); } catch (SecurityException ex) { throw new RuntimeException( "Problem getting static main on " + className, ex); } int modifiers = m.getModifiers(); if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) { throw new RuntimeException( "Main method is not public and static on " + className); } /* * This throw gets caught in ZygoteInit.main(), which responds * by invoking the exception"s run() method. This arrangement * clears up all the stack frames that were required in setting * up the process. */ // 拋出異常 throw new ZygoteInit.MethodAndArgsCaller(m, argv); }
看到這里一定會(huì)奇怪,為何在此處拋出一個(gè)異常:throw new ZygoteInit.MethodAndArgsCaller(m, argv);,這里我們需要往前回溯看看,到底在哪里捕獲的異常。結(jié)果是發(fā)現(xiàn)在ZygoteInit.java的main中進(jìn)行的捕獲:
try { ...... if (startSystemServer) { startSystemServer(abiList, socketName); } ...... } catch (MethodAndArgsCaller caller) { caller.run(); }
調(diào)用的起始也是從這里開始的,好吧,我們看看捕獲到異常之后做了什么。調(diào)用了caller.run()。拋出異常的時(shí)候已經(jīng)new了一個(gè)throw new ZygoteInit.MethodAndArgsCaller(m, argv);這個(gè)對(duì)象了,并且參數(shù)給出的就是SystemServer類的main方法,那么繼續(xù)看ZygoteInit.MethodAndArgsCaller:
public static class MethodAndArgsCaller extends Exception implements Runnable { /** method to call */ private final Method mMethod; /** argument array */ private final String[] mArgs; public MethodAndArgsCaller(Method method, String[] args) { mMethod = method; mArgs = args; } public void run() { try { mMethod.invoke(null, new Object[] { mArgs }); } catch (IllegalAccessException ex) { throw new RuntimeException(ex); } catch (InvocationTargetException ex) { Throwable cause = ex.getCause(); if (cause instanceof RuntimeException) { throw (RuntimeException) cause; } else if (cause instanceof Error) { throw (Error) cause; } throw new RuntimeException(ex); } } }
run方法就是調(diào)用了一下這個(gè)方法,也就是調(diào)用了SystemServer的main方法,直接跳到main方法執(zhí)行了。但是為何這么做呢?這里有個(gè)疑問(wèn)。其實(shí)仔細(xì)想想也挺有意思。這一串調(diào)用從startSystemServer開始執(zhí)行了比較深了,每次執(zhí)行函數(shù)方法的時(shí)候都會(huì)伴隨著出現(xiàn)局部變量,那么就會(huì)直接開辟在棧上,之后的SystemServer又是個(gè)常駐不退出的進(jìn)程,那么棧上面的這些空間也就意味著并不會(huì)釋放,而啟動(dòng)過(guò)程只會(huì)執(zhí)行一次,后面沒(méi)用了,這些東西沒(méi)有清理就一直存在。這里直接拋出異常后,在startSystemServer這個(gè)最初的位置捕獲,會(huì)導(dǎo)致異常發(fā)生后直接跳到捕獲的地方,之前所有的棧全部被清空。這下子明白了吧。google很聰明的利用了異常的做法回溯了棧,釋放不用的內(nèi)存。真是非常聰明!
至此本文結(jié)束。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/67896.html
摘要:孵化進(jìn)程相當(dāng)于是系統(tǒng)的根進(jìn)程,后面所有的進(jìn)程都是通過(guò)這個(gè)進(jìn)程出來(lái)的雖然進(jìn)程相當(dāng)于系統(tǒng)的根進(jìn)程,但是事實(shí)上它也是由系統(tǒng)的進(jìn)程啟動(dòng)的。 目錄介紹 1.什么是Zygote進(jìn)程 1.1 簡(jiǎn)單介紹 1.2 各個(gè)進(jìn)程的先后順序 1.3 進(jìn)程作用說(shuō)明 2.Zygote進(jìn)程的啟動(dòng)流程 2.1 源碼位置 2.2 ZygoteInit類的main方法 2.3 registerZygoteSo...
摘要:入口函數(shù)是創(chuàng)建確認(rèn)是進(jìn)程執(zhí)行進(jìn)程如果忽略掉參數(shù)這些細(xì)節(jié),剩下的就是的建立和調(diào)用的方法了,啟動(dòng)的是。下面再看下其實(shí)主要的就是這句話,前面的都是參數(shù)的配置。至此為止,的過(guò)程基本分析完畢。 android也是基于linux的系統(tǒng),因此所有的進(jìn)程都是從init進(jìn)程開始的(直接或間接的從init進(jìn)程fock出來(lái)的)。Zygote是受精卵進(jìn)程,也是系統(tǒng)啟動(dòng)過(guò)程中由init進(jìn)程創(chuàng)建的,具體的看下啟動(dòng)...
閱讀 2091·2021-11-23 10:13
閱讀 2799·2021-11-09 09:47
閱讀 2743·2021-09-22 15:08
閱讀 3323·2021-09-03 10:46
閱讀 2239·2019-08-30 15:54
閱讀 921·2019-08-28 18:09
閱讀 2433·2019-08-26 18:26
閱讀 2346·2019-08-26 13:48