Zygote进程的启动-Java篇

​ Zygote进程是Android中Java世界的第一个进程,同时它也是Android中所有Java进程的父进程(Android所有的Java进程都从Zygote进程fork)。前面讲完了init进程到Zygote进程,只是讲述了nitive层的init进程启动及如何拉起Zygote进程,在上篇文章中最后讲到的是,app_process.cpp的main方法通过JNI,调用com.android.internal.os.ZygoteInit.java的main方法。

ZygoteInit.java main方法。

public static void main(String argv[]) {
        ZygoteServer zygoteServer = null;

        // Mark zygote start. This ensures that thread creation will throw
        // an error.  标记zygote开始启动,不让创建线程
        ZygoteHooks.startZygoteNoThreadCreation();

        // Zygote goes into its own process group. zygote进入自己的进程组
        try {
            Os.setpgid(0, 0);
        } catch (ErrnoException ex) {
            throw new RuntimeException("Failed to setpgid(0,0)", ex);
        }

        Runnable caller;
        try {
            // Report Zygote start time to tron unless it is a runtime restart 向tron报告Zygote启动时间,除非它是运行时重新启动
            if (!"1".equals(SystemProperties.get("sys.boot_completed"))) {
                MetricsLogger.histogram(null, "boot_zygote_init",
                        (int) SystemClock.elapsedRealtime());
            }

            String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
            TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag,
                    Trace.TRACE_TAG_DALVIK);
            bootTimingsTraceLog.traceBegin("ZygoteInit");
            RuntimeInit.preForkInit();//fork 预备工作?

            boolean startSystemServer = false;
            String zygoteSocketName = "zygote";
            String abiList = null;
            boolean enableLazyPreload = false;
            for (int i = 1; i < argv.length; i++) {
                if ("start-system-server".equals(argv[i])) {
                    startSystemServer = true;//会走这里
                } else if ("--enable-lazy-preload".equals(argv[i])) {
                    enableLazyPreload = 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)) {//没有这个
                    zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());
                } else {
                    throw new RuntimeException("Unknown command line argument: " + argv[i]);
                }
            }

            final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME); //true

            if (abiList == null) {//不为空
                throw new RuntimeException("No ABI list supplied.");
            }

            // In some configurations, we avoid preloading resources and classes eagerly.在某些配置中,我们避免急于预加载资源和类。
            // In such cases, we will preload things prior to our first fork.在这种情况下,我们将在第一个分叉之前预装东西。
            if (!enableLazyPreload) {//会走这里,好像是预加载一些东西。看下面的变量名,是跟log有关?
                bootTimingsTraceLog.traceBegin("ZygotePreload");
                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                        SystemClock.uptimeMillis());
                preload(bootTimingsTraceLog);
                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                        SystemClock.uptimeMillis());
                bootTimingsTraceLog.traceEnd(); // ZygotePreload
            }

            // Do an initial gc to clean up after startup  启动后进行初始gc清理
            bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
            gcAndFinalize();//开始之前先清理一下?
            bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC

            bootTimingsTraceLog.traceEnd(); // ZygoteInit
            /*
            * 调用native方法初始化zygote,包括 获取socket ,初始化安全属性 加载新能配置文件等等
            */
            Zygote.initNativeState(isPrimaryZygote);//isPrimaryZygote = true   

            ZygoteHooks.stopZygoteNoThreadCreation();//跟前面的startZygoteNoThreadCreation对应,到这应该zygote创建出来了,可以允许创建线程了

            zygoteServer = new ZygoteServer(isPrimaryZygote);//创建一个ZygoteServer对象,isPrimaryZygote 用来区分是zygote还是zygote的子进程

            if (startSystemServer) {//这里是true
                //孵化出 system server进程
                Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
                // 这里边有意思的是 调用上面的forkSystemServer 进行孵化 system server进程的时候,fork出的进程(新进程是:system server),程序也是运行到这里,相当与复制一样。两个进程都运行着同一套代码,但是这两个进程会在forkSystemServer方法得到不同的返回值,然后下面开始分道扬镳,走各自的路。
                // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
                // child (system_server) process. 
                /*
                * 如果是父进程(即:zygote进程),r是null
                * 如果是子进程(在这里就是:system server)
                */
                if (r != null) {
                    r.run(); //所以zygote进程不会进来这里,但是system server进程会走到这里
                    return;
                }
            }
            //zygote进程会走到这里
            Log.i(TAG, "Accepting command socket connections");

            // The select loop returns early in the child process after a fork and
            // loops forever in the zygote.
            //zygote进程开启循环 ,等待socket连接,有请求的时候,就去fork新进程
            caller = zygoteServer.runSelectLoop(abiList);//返回来的caller是子进程的Runnable,
        } catch (Throwable ex) {
            Log.e(TAG, "System zygote died with exception", ex);
            throw ex;
        } finally {
            if (zygoteServer != null) {//断开socket连接
                zygoteServer.closeServerSocket();
            }
        }

        // We're in the child process and have exited the select loop. Proceed to execute the
        // command.
        if (caller != null) {//非System server子进程,在这里调用,子进程开始自己的任务
            caller.run();
        }
    }

总结

​ 在上述的main方法中,主要做的事情:

  1. zygote进程创建的时候,不允许创建线程
  2. RuntimeInit.preForkInit(); fork 预备工作
  3. 参数解析,判断是不是zygote模式
  4. 做一些清理工作
  5. Zygote.initNativeState(isPrimaryZygote),调用native方法,获取socket、加载配置文件等
  6. 开放创建线程,与1对应
  7. 创建一个ZygoteServer对象
  8. 调用forkSystemServer,孵化system server进程
  9. 当system server进程孵化出来之后,两个进程开始分道扬镳
    1. zygote进程:开启循环,等待socket客户端请求到来,孵化新进程。然后调用runSelectLoop方法返回的Runnable对象的run方法,开始子进程的任务
    2. system server进程:运行forkSystemServer方法返回的Runnable对象的run方法,开始自己的任务

到这,Zygote进程就启动起来了,同时它也拉起了System server进程,而自己进入了循环状态

results matching ""

    No results matching ""