Android 8.1 源码_启动篇(二) -- 深入研究 zygote

Android中,zygote是整个系统创建新进程的核心进程。zygote进程在内部会先启动Dalvik虚拟机,继而加载一些必要的系统资源和系统类,最后进入一种监听状态。在之后的运作中,当其他系统模块(比如 AMS)希望创建新进程时,只需向zygote进程发出请求,zygote进程监听到该请求后,会相应地fork出新的进程,于是这个新进程在初生之时,就先天具有了自己的Dalvik虚拟机以及系统资源。

开篇 核心源码 关键类 路径
init.rc   system/core/rootdir/init.rc  
init.cpp   system/core/init/init.cpp  
init.zygote64.rc   system/core/rootdir/init.zygote64.rc  
builtins.cpp   system/core/init/builtins.cpp  
service.cpp   system/core/init/service.cpp  
app_main.cpp   frameworks/base/cmds/app_process/app_main.cpp  
AndroidRuntime.cpp   frameworks/base/core/jni/AndroidRuntime.cpp  
JniInvocation.cpp   libnativehelper/JniInvocation.cpp  
ZygoteInit.java   frameworks/base/core/java/com/android/internal/os/ZygoteInit.java  
ZygoteServer.java   frameworks/base/core/java/com/android/internal/os/ZygoteServer.java  
Zygote简介

在Android系统中,JavaVM(Java虚拟机)、应用程序进程以及运行系统的关键服务的SystemServer进程都是由Zygote进程来创建的,我们也将它称为孵化器。它通过fock(复制进程)的形式来创建应用程序进程和SystemServer进程,由于Zygote进程在启动时会创建JavaVM,因此通过fock而创建的应用程序进程和SystemServer进程可以在内部获取一个JavaVM的实例拷贝。

Read The Fucking Code Zygote触发

在分析init进程时,我们知道init进程启动后,会解析init.rc文件,然后创建和加载service字段指定的进程。zygote进程就是以这种方式,被init进程加载的。

在system/core/rootdir/init.rc的开始部分,可以看到:

import /init.environ.rc import /init.usb.rc import /init.${ro.hardware}.rc import /vendor/etc/init/hw/init.${ro.hardware}.rc import /init.usb.configfs.rc import /init.${ro.zygote}.rc // ${ro.zygote}由厂商定义,与平台相关 on early-init # Set init and its forked children's oom_adj. write /proc/1/oom_score_adj -1000 init.zygoteXX.rc

从之前分析的init篇中我们知道,在不同的平台(32、64及64_32)上,init.rc将包含不同的zygote.rc文件。在system/core/rootdir目录下,有init.zygote32_64.rc、init.zyote64.rc、 init.zyote32.rc、init.zygote64_32.rc。

      ✨ init.zygote32.rc:zygote 进程对应的执行程序是 app_process (纯 32bit 模式)
      ✨ init.zygote64.rc:zygote 进程对应的执行程序是 app_process64 (纯 64bit 模式)
      ✨ init.zygote32_64.rc:启动两个 zygote 进程 (名为 zygote 和 zygote_secondary),对应的执行程序分别是 app_process32 (主模式)、app_process64
      ✨ init.zygote64_32.rc:启动两个 zygote 进程 (名为 zygote 和 zygote_secondary),对应的执行程序分别是 app_process64 (主模式)、app_process32

为什么要定义这么多种情况呢?直接定义一个不就好了,这主要是因为Android 5.0以后开始支持64位程序,为了兼容32位和64位才这样定义。不同的zygote.rc内容大致相同,主要区别体现在启动的是32位,还是64位的进程。init.zygote32_64.rc和init.zygote64_32.rc会启动两个进程,且存在主次之分。

这里拿64位处理器为例,init.zygote64_32.rc的代码如下所示:

// 进程名称是zygote,运行的二进制文件在/system/bin/app_process64 // 启动参数是 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote class main priority -20 user root group root readproc socket zygote stream 660 root system // 创建一个socket,名字叫zygote,以tcp形式 onrestart write /sys/android_power/request_state wake // onrestart 指当进程重启时执行后面的命令 onrestart write /sys/power/state on onrestart restart audioserver onrestart restart cameraserver onrestart restart media onrestart restart netd onrestart restart wificond writepid /dev/cpuset/foreground/tasks // 创建子进程时,向 /dev/cpuset/foreground/tasks 写入pid // 另一个service ,名字 zygote_secondary service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary --enable-lazy-preload class main priority -20 user root group root readproc socket zygote_secondary stream 660 root system onrestart restart zygote writepid /dev/cpuset/foreground/tasks start zygote

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zygdyw.html