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);
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2021-04-25 系统调用学习