Zygote进程创建过程

Zygote进程

  • Zygote进程是用户层第一个进程init启动的,Zygote是第一个app进程。android系统其他所有的APP进程都是由Zygote进程fork的。
  • Zygote进程本身是分为native部分和java层部分的,native部分的代码在frameworks/base/cmds/app_process/app_main.cpp中,对应的elf可执行文件就是app_process。

Zygote进程启动过程

  • app_main.cpp是Zygote进程的native部分,init进程启动Zygote进程会执行app_main.cpp的main()函数。
    main函数的最后会调用AndroidRuntime类对象的成员函数start,传入的第一个参数是Zygote进程的java层初始化类名称。

  • AndroidRuntime::start函数

  • start函数中接着会调用 jni_invocation.Init(NULL)来加载对应的虚拟机so库,查询导出的三个接口函数(JNI_GetDefaultJavaVMInitArgs, JNI_CreateJavaVM, JNI_GetCreatedJavaVMs)

  • start函数接着会调用startVm,此函数内部会调用JNI_CreateJavaVM创建虚拟机实例

  • 然后调用OnVmCreated()通知调用者(app_process)虚拟机初始化完成。接着调用startReg注册android 核心类的JNI方法。

  • 最后通过刚才创建的虚拟机实例,通过反射调用Zygote的java层入口:ZygoteInit的main函数。

  • Zygote进程的java层初始化类名称为ZygoteInit, 对应的源码在frameworks/base/core/java/android/os/ZygoteProcess.java中,ZygoteInit类的main方法为其入口。
  • 创建一个socket,建立IPC通信的服务端,用来和system_server进程的ActivityManagerService通讯。
  • 预加载类和资源
  • 其会创建一个system_server子进程(fock)
  • 执行runSelectLoop进入死循环接收来自客户端的请求。
public static void main(String argv[]) {
    try {
        // 开始配置Zygote进程的初始化工作
        SamplingProfilerIntegration.start();

        // 创建一个socket,建立IPC通信的服务端,用来和ActivityManagerService通讯。
        registerZygoteSocket();
        EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
            SystemClock.uptimeMillis());
        // 预加载类和资源
        preload();
        EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
            SystemClock.uptimeMillis());

        // 结束配置Zygote的初始化
        SamplingProfilerIntegration.writeZygoteSnapshot();

        // 进行一次垃圾回收
        gc();

        // 禁用跟踪
        Trace.setTracingEnabled(false);

        // If requested, start system server directly from Zygote
        if (argv.length != 2) {
            throw new RuntimeException(argv[0] + USAGE_STRING);
        }

        if (argv[1].equals("start-system-server")) {
            startSystemServer();//启动system_server进程
        } else if (!argv[1].equals("")) {
            throw new RuntimeException(argv[0] + USAGE_STRING);
        }

        Log.i(TAG, "Accepting command socket connections");
        // 处理客户连接和客户请求(等待ActivityMangerService(在SystemServer进程中)的连接,并fork一个新的进程)
        runSelectLoop();
        // 关闭服务端
        closeServerSocket();
    } catch (MethodAndArgsCaller caller) {
        caller.run();
    } catch (RuntimeException ex) {
        Log.e(TAG, "Zygote died with exception", ex);
        closeServerSocket();
        throw ex;
    }
}
  • ZygoteInit的main函数会调用startSystemServer,
  • 在startSystemServer中调用forkSystemServer(最终会调用fork系统函数)fork一个进程启动SystemServer组件。
  • fork的这个进程返回值 pid = 0,接着这个新fork的进程会执行handleSystemServerProcess函数。
/**
 * Prepare the arguments and fork for the system server process.
 */
private static boolean startSystemServer(String abiList, String socketName)
        throws MethodAndArgsCaller, RuntimeException {
    long capabilities = posixCapabilitiesAsBits(
        OsConstants.CAP_BLOCK_SUSPEND,
        OsConstants.CAP_KILL,
        OsConstants.CAP_NET_ADMIN,
        OsConstants.CAP_NET_BIND_SERVICE,
        OsConstants.CAP_NET_BROADCAST,
        OsConstants.CAP_NET_RAW,
        OsConstants.CAP_SYS_MODULE,
        OsConstants.CAP_SYS_NICE,
        OsConstants.CAP_SYS_RESOURCE,
        OsConstants.CAP_SYS_TIME,
        OsConstants.CAP_SYS_TTY_CONFIG
    );
    /* Hardcoded command line to start the system server */
    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",
    };
    ZygoteConnection.Arguments parsedArgs = null;

    int pid;

    try {
        parsedArgs = new ZygoteConnection.Arguments(args);
        ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
        ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

        /* Request to fork the system server process */
        //新建的进程返回值pid会等于0
        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);
        }

        handleSystemServerProcess(parsedArgs);
    }

    return true;
}
  • Zygote新fork的SystemServer进程会直接执行handleSystemServerProcess(parsedArgs)函数
  • 然后handleSystemServerProcess会继续执行 RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
/**
* Finish remaining work for the newly forked system server process.
*/
private static void handleSystemServerProcess(
        ZygoteConnection.Arguments parsedArgs)
        throws ZygoteInit.MethodAndArgsCaller {
    
    //因为新创建的进程是在Zygote进程中启动的,所以该进程也会继承那个Socket,这里先将这个socket关闭掉
    closeServerSocket();

    // set umask to 0077 so new files and directories will default to owner-only permissions.
    Os.umask(S_IRWXG | S_IRWXO);

    if (parsedArgs.niceName != null) {
        Process.setArgV0(parsedArgs.niceName);
    }

    final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
    if (systemServerClasspath != null) {
        performSystemServerDexOpt(systemServerClasspath);
    }

    if (parsedArgs.invokeWith != null) {
        String[] args = parsedArgs.remainingArgs;
        // If we have a non-null system server class path, we'll have to duplicate the
        // existing arguments and append the classpath to it. ART will handle the classpath
        // correctly when we exec a new process.
        if (systemServerClasspath != null) {
            String[] amendedArgs = new String[args.length + 2];
            amendedArgs[0] = "-cp";
            amendedArgs[1] = systemServerClasspath;
            System.arraycopy(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length);
        }

        WrapperInit.execApplication(parsedArgs.invokeWith,
                parsedArgs.niceName, parsedArgs.targetSdkVersion,
                VMRuntime.getCurrentInstructionSet(), null, args);
    } else {
        ClassLoader cl = null;
        if (systemServerClasspath != null) {
            cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader());
            Thread.currentThread().setContextClassLoader(cl);
        }

        /*
            * Pass the remaining arguments to SystemServer.
            */
        RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
    }

    /* should never reach here */
}
  • RuntimeInit.zygoteInit()函数的第二个参数包含了com.android.server.SystemServer类名
  • RuntimeInit.zygoteInit()函数继续调用nativeZygoteInit(),这个native方法会初始化一个Binder用来做进程通讯。
  • applicationInit(targetSdkVersion, argv, classLoader)方法会调用 invokeStaticMain(args.startClass, args.startArgs, classLoader)。
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller {
    if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");

    //将 System.out 和 System.err 定向到Android日志中
    redirectLogStreams();
    commonInit();
    nativeZygoteInit();
    applicationInit(targetSdkVersion, argv, classLoader);
}
  • invokeStaticMain(args.startClass, args.startArgs, classLoader)方法中会调用com.android.server.SystemServer这个类的main入口方法。
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
        throws ZygoteInit.MethodAndArgsCaller {
    Class<?> cl;

    try {
        cl = Class.forName(className, true, classLoader);
    } catch (ClassNotFoundException ex) {
        throw new RuntimeException(
                "Missing class when invoking static main " + className,
                ex);
    }

    Method m;
    try {

        //调用main方法
        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);
}
  • SystemServer类的main方法在frameworks\base\services\java\com\android\server\SystemServer.java中
  • Android系统的核心服务AMS、WMS、PMS等就是在run()方法里进行创建和初始化的,当它们创建之后,会通过ServiceManager的add_server()方法把它们加入到ServiceManager中统一管理
  • main方法调用后,SystemServer进程就启动了。
public static void main(String[] args) {
    new SystemServer().run();
}

APP进程的启动过程

  • 当点击Launcher主界面的一个应用程序图标时,如果这个应用程序还未曾启动就会通过Binder通知SystemServer进程的AMS调用startProcessLocked()方法启动进程。
  • AMS的startProcessLocked()方法调用Process类的start()方法为应用程序创建新的进程
  • 这里的参数entryPoint为“android.app.ActivityThread”,当最后进程被fork出来后会先执行这个类的main函数,app进程真正的入口。
private final void startProcessLocked(ProcessRecord app, String hostingType,
        String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
    ......
    if (entryPoint == null) entryPoint = "android.app.ActivityThread";
    ......
    ProcessStartResult startResult;
    startResult = Process.start(entryPoint,
                    app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                    app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,app.info.dataDir, invokeWith, entryPointArgs);
        }
    .......
}
  • Process类的start()直接调用了ZygoteProcess类的start()方法,该start()方法直接调用了ZygoteProcess类的startViaZygote()方法。
  • 设置值,包括uid、gid
  • 调用openZygoteSocketIfNeeded()方法来链接“zygote”Socket,链接Socket成功之后
private Process.ProcessStartResult startViaZygote(final String processClass,final String niceName,final int uid, final int gid,final int[] gids,int runtimeFlags, int mountExternal,int targetSdkVersion,String seInfo,String abi,String instructionSet,String appDataDir,String invokeWith,String[] extraArgs)throws ZygoteStartFailedEx {
    ArrayList<String> argsForZygote = new ArrayList<String>();
    argsForZygote.add("--runtime-args");
    argsForZygote.add("--setuid=" + uid);
    argsForZygote.add("--setgid=" + gid);
    ......
    synchronized(mLock) {
        return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
    }
}
  • 方法中的mSocket的值是“zygote”,通过connect()方法去链接“zygote”Socket。
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
    .......
    if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
        try {
            primaryZygoteState = ZygoteState.connect(mSocket);
        }
    .......
}
  • 然后ZygoteInit.runSelectLoop()循环等待ActivityManagerService(其在SystemServer进程中)来连接去创建的socket就会返回,连接后会调用runOnce()函数fork一个进程。
private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
    ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
    ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
    fds.add(sServerSocket.getFileDescriptor());
    peers.add(null);
    while (true) {
        StructPollfd[] pollFds = new StructPollfd[fds.size()];
        for (int i = 0; i < pollFds.length; ++i) {
            pollFds[i] = new StructPollfd();
            pollFds[i].fd = fds.get(i);
            pollFds[i].events = (short) POLLIN;
        }
        try {
            Os.poll(pollFds, -1);
        } catch (ErrnoException ex) {
            throw new RuntimeException("poll failed", ex);
        }
        for (int i = pollFds.length - 1; i >= 0; --i) {
            if ((pollFds[i].revents & POLLIN) == 0) {
                continue;
            }
            if (i == 0) {
                ZygoteConnection newPeer = acceptCommandPeer(abiList);
                peers.add(newPeer);
                fds.add(newPeer.getFileDesciptor());
            } else {
                boolean done = peers.get(i).runOnce();
                if (done) {
                    peers.remove(i);
                    fds.remove(i);
                }
            }
        }
    }
}
  • runOnce函数通过forkAndSpecialize函数,forkAndSpecialize函数最终会调用fork系统函数进而fork一个进程。
  • fork返回后,判断pid = 0 说明是子进程,继续调用handleChildProc,此函数会直接调用主类ActivityThread.java的main()函数(app进程真正的入口)
  • fork是Linux系统的系统调用,用于复制当前进程,产生一个新的进程。新进程被创建后,和父进程共享已经分配的内存空间,除了进程ID外,新进程拥有和父进程完全相同的进程信息,直到向内存写入数据时,操作系统才复制一份目标地址空间,并将要写的数据写入到新的地址空间中,这就是所谓的copy-on-write机制。
boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
	String args[];
	Arguments parsedArgs = null;
	FileDescriptor[] descriptors;
	try {
		args = readArgumentList();
		descriptors = mSocket.getAncillaryFileDescriptors();
	} catch (IOException ex) {
		Log.w(TAG, "IOException on command socket " + ex.getMessage());
		closeSocket();
		return true;
	}
	if (args == null) {
		// EOF reached.
		closeSocket();
		return true;
	}
	/** the stderr of the most recent request, if avail */
	PrintStream newStderr = null;
 
	if (descriptors != null && descriptors.length >= 3) {
		newStderr = new PrintStream(
				new FileOutputStream(descriptors[2]));
	}
	int pid = -1;
	FileDescriptor childPipeFd = null;
	FileDescriptor serverPipeFd = null;
	try {
		parsedArgs = new Arguments(args);
		applyUidSecurityPolicy(parsedArgs, peer);
		applyRlimitSecurityPolicy(parsedArgs, peer);
		applyCapabilitiesSecurityPolicy(parsedArgs, peer);
		applyInvokeWithSecurityPolicy(parsedArgs, peer);
		applyDebuggerSystemProperty(parsedArgs);
		applyInvokeWithSystemProperty(parsedArgs);
		int[][] rlimits = null;
		if (parsedArgs.rlimits != null) {
			rlimits = parsedArgs.rlimits.toArray(intArray2d);
		}
		if (parsedArgs.runtimeInit && parsedArgs.invokeWith != null) {
			FileDescriptor[] pipeFds = Libcore.os.pipe();
			childPipeFd = pipeFds[1];
			serverPipeFd = pipeFds[0];
			ZygoteInit.setCloseOnExec(serverPipeFd, true);
		}
		//复制新进程
		pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,
				parsedArgs.gids, parsedArgs.debugFlags, rlimits);
	} catch (IOException ex) {
		logAndPrintError(newStderr, "Exception creating pipe", ex);
	} catch (ErrnoException ex) {
		logAndPrintError(newStderr, "Exception creating pipe", ex);
	} catch (IllegalArgumentException ex) {
		logAndPrintError(newStderr, "Invalid zygote arguments", ex);
	} catch (ZygoteSecurityException ex) {
		logAndPrintError(newStderr,
				"Zygote security policy prevents request: ", ex);
	}
	try {
		//区分父子进程
		if (pid == 0) {
			// in child
			IoUtils.closeQuietly(serverPipeFd);
			serverPipeFd = null;
                        //执行对应的主类ActivityThread.java的main()函数
			handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
			// should never get here, the child is expected to either
			// throw ZygoteInit.MethodAndArgsCaller or exec().
			return true;
		} else {
			// in parent...pid of < 0 means failure
			IoUtils.closeQuietly(childPipeFd);
			childPipeFd = null;
			return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
		}
	} finally {
		IoUtils.closeQuietly(childPipeFd);
		IoUtils.closeQuietly(serverPipeFd);
	}
}
posted @ 2022-04-25 13:02  怎么可以吃突突  阅读(206)  评论(0编辑  收藏  举报