Zygote简介
Zygote翻译为受精卵,主要用于孵化子进程。
所有的应用程序进程以及System Server进程都由Zygote进程通过fork函数孵化出来。
Zygote进程的触发
在init.rc与init.zygoteXX.rc中触发,可以查看梳理init进程文章。
Zygote进程的启动过程
main函数中传入的参数argv是
-Xzygote /system/bin --zygote --start-system-server
接着进行字符串比较如果是zygote服务zygote = true
如果是start-system-server命令 则startSystemServer = true
接下来把start-system-server放入了args
然后通过runtime.start启动进程
startVm创建虚拟机
查看startVM
代码比较多截取一部分
startVm方法中先进行了一些虚拟机参数的初始化,然后调用了JNI_CreateJavaVM方法
调用runtime.cc的Create(RuntimeArgumentMap&& runtime_options)方法
调用Init方法
创建堆管理对象
创建Java虚拟机对象、attach主线程,创建类连接器,初始化类连接器
startReg()注册JNI函数
AndroidRuntime.start()执行到最后通过反射调用到ZygoteInit.main(),
ZygoteInit.main()
1.创建Zygote服务端
2.注册Socket
3.preload资源,提前将进程所需要的资源加载,例如class、resources、openGL、公共的library、Text字体资源等。
4.进行一次资源的gc
5.forkSystemServer
6.zygoteServer.runSelectLoop
Zygote采用高效的I/O多路复用机制,保证在没有客户端连接请求或数据处理时休眠,否则响应客户端的请求。
forkSystemServer
Zygote.forkSystemServer
Zygote.forkSystemServer调用nativeForkSystemServer
nativeForkSystemServer是jni方法,对应的实现在
/frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
当system_server进程创建失败时,将会重启zygote进程。这里需要注意,对于Android 5.0以上系统,有两个zygote进程,分别是zygote、zygote64两个进程,system_server的父进程,一般来说64位系统其父进程是zygote64进程
- 当kill system_server进程后,只重启zygote64和system_server,不重启zygote;
- 当kill zygote64进程后,只重启zygote64和system_server,也不重启zygote;
- 当kill zygote进程,则重启zygote、zygote64以及system_server。
到此system_server进程就创建起来了,接下来进入handleSystemServerProcess方法进行初始化
ZygoteServer.closeServerSocket
forkSystemServer后会调用ZygoteServer.closeServerSocket关闭socket
handleSystemServerProcess()
调用 handleSystemServerProcess()完成system_server进程剩余的初始化工作
performSystemServerDexOpt
ZygoteInit.zygoteInit()
RuntimeInit.redirectLogStreams()
RuntimeInit.redirectLogStreams() 将System.out 和 System.err 输出重定向到Android 的Log系统(定义在 android.util.Log)
RuntimeInit.commonInit();
RuntimeInit.commonInit(); //设置了一个未捕捉异常处理方法
LogManager.getLogManager().reset();//重置log配置
设置默认的HTTP User-agent格式,用于 HttpURLConnection。
NetworkManagementSocketTagger.install();// 设置socket的tag,用于网络流量统计
ZygoteInit.nativeZygoteInit();
nativeZygoteInit()方法在AndroidRuntime.cpp中,进行了jni映射,对应下面的方法。
此处的gCurRuntime为AppRuntime,是在AndroidRuntime.cpp中定义的
proc->startThreadPool();//启动新binder线程
ProcessState::self()是单例模式,主要工作是调用open()打开/dev/binder驱动设备,再利用mmap()映射内核的地址空间,将Binder驱动的fd赋值ProcessState对象中的变量mDriverFD,用于交互操作。startThreadPool()是创建一个新的binder线程,不断进行talkWithDriver(),
applicationInit()
findStaticMain(args.startClass, args.startArgs, classLoader)
调用startClass的static方法 main()
在startSystemServer()方法中通过硬编码初始化参数,可知此处args.startClass为”com.android.server.SystemServer”。
根据注释:此抛出被ZygoteInit.main()捕获,这样做好处是能清空栈帧,提高栈帧利用率。
回到ZygoteInit.main()中
此处调用MethodAndArgsCaller的run方法
根据传递过来的参数,可知此处通过反射调用SystemServer的main方法。
zygoteServer.runSelectLoop
该方法的主要功能
- 客户端通过openZygoteSocketIfNeeded()来跟zygote进程建立连接。zygote进程收到客户端连接请求后执行accept();然后再创建ZygoteConnection对象,并添加到fds数组列表;
- 建立连接之后,可以跟客户端通信,进入processOneCommand()方法来接收客户端数据,并执行进程创建工作。
如果i>0 表示通过socket接收来自对端的数据,执行ZygoteConnection的processOneCommand方法:
Runnable processOneCommand(ZygoteServer zygoteServer) {
124 String args[];
125 Arguments parsedArgs = null;
126 FileDescriptor[] descriptors;
127
128 try {
129 args = readArgumentList();//读取socket客户端发送过来的参数列表
130 descriptors = mSocket.getAncillaryFileDescriptors();
131 } catch (IOException ex) {
132 throw new IllegalStateException("IOException on command socket", ex);
133 }
......
145
146 parsedArgs = new Arguments(args);//将binder客户端传递过来的参数,解析成Arguments对象格式
......
234 pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
235 parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
236 parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.startChildZygote,
237 parsedArgs.instructionSet, parsedArgs.appDataDir);
238
239 try {
240 if (pid == 0) {
241 // in child 子进程
242 zygoteServer.setForkChild();
243
244 zygoteServer.closeServerSocket();
245 IoUtils.closeQuietly(serverPipeFd);
246 serverPipeFd = null;
247
248 return handleChildProc(parsedArgs, descriptors, childPipeFd,
249 parsedArgs.startChildZygote);
250 } else {
251 // In the parent. A pid < 0 indicates a failure and will be handled in
252 // handleParentProc.
253 IoUtils.closeQuietly(childPipeFd);
254 childPipeFd = null;
255 handleParentProc(pid, descriptors, serverPipeFd);
256 return null;
257 }
258 } finally {
259 IoUtils.closeQuietly(childPipeFd);
260 IoUtils.closeQuietly(serverPipeFd);
261 }
262 }
通过 Zygote.forkAndSpecialize创建新进程,pid=0时调用handleChildProc 进入子进程执行流程
总结
- init 根据init.rc 运行 app_process, 并携带‘–zygote’ 和 ’–startSystemServer’ 参数。
- AndroidRuntime.cpp::start() 里将启动JavaVM,并且注册所有framework相关的系统JNI接口。
- 第一次进入Java世界,运行ZygoteInit.java::main() 函数初始化Zygote. Zygote 并创建Socket的
server 端。 - 然后fork一个新的进程并在新进程里初始化SystemServer. Fork之前,Zygote是preload常用的
Java类库,以及系统的resources,同时GC()清理内存空间,为子进程省去重复的工作。 - SystemServer 里将所有的系统Service初始化,包括ActivityManager 和 WindowManager, 他们
是应用程序运行起来的前提。 - 依次同时,Zygote监听服务端Socket,等待新的应用启动请求。
- ActivityManager ready 之后寻找系统的“Startup” Application, 将请求发给Zygote。 8. Zygote收到请求后,fork出一个新的进程。
- Zygote监听并处理SystemServer 的 SIGCHID 信号,一旦System Server崩溃,立即将自己杀死。
init会重启Zygote.