Android 14 Zygote进程解析
2024-03-02 / 龙之叶   

前言

init进程启动后,最重要的一个进程就是Zygote进程,Zygote是所有应用的鼻祖。SystemServer和其他所有Dalivik虚拟机进程都是由Zygote fork而来。
Zygote进程由app_process启动,Zygote是一个C/S模型,Zygote进程作为服务端,其他进程作为客户端向它发出“孵化-fork”请求,而Zygote接收到这个请求后就“孵化-fork”出一个新的进程。
由于Zygote进程在启动时会创建Java虚拟机,因此通过fork而创建的应用程序进程和SystemServer进程可以在内部获取一个Java虚拟机的实例拷贝。
架构图

Zygote是如何启动的

init进程启动后,会解析init.rc文件,然后创建和加载service字段指定的进程。zygote进程就是以这种方式,被init进程加载的。
system/core/rootdir/init.rc

1
import /system/etc/init/hw/init.${ro.zygote}.rc

其中${ro.zygote} 由各个厂家使用,现在的主流厂家基本使用zygote64_32,因此,我们的rc文件为 init.zygote64_32.r。它会启动两个zygote进程(名为zygote和zygote——secondary),对应的执行程序分别是app_prcocess64(主模式)、app_process32。
init.zygote64_32.rc
system/core/rootdir/init.zygote64_32.rc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
class main
priority -20
user root //用户为root
group root readproc reserved_disk //访问组支持root readproc reserved_disk
socket zygote stream 660 root system //创建一个socket,名字叫zygote,以tcp形式,可以在/dev/socket 中看到一个 zygote的socket
socket usap_pool_primary stream 660 root system
onrestart exec_background - system system -- /system/bin/vdc volume abort_fuse
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
onrestart restart wificond
task_profiles ProcessCapacityHigh MaxPerformance
critical window=${zygote.critical_window.minute:-off} target=zygote-fatal

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 reserved_disk
socket zygote_secondary stream 660 root system
socket usap_pool_secondary stream 660 root system
onrestart restart zygote
task_profiles ProcessCapacityHigh MaxPerformance

从上面一段代码可以看出:
第一个Zygote进程:
进程名:zygote
进程通过 /system/bin/app_process64来启动
启动参数: -Xzygote
/system/bin
–zygote
–start-system-server
–socket-name=zygote
socket的名称:zygote
第二个Zygote进程:
进程名:zygote_secondary
进程通过 /system/bin/app_process32来启动
启动参数: -Xzygote
/system/bin
–zygote
–socket-name=zygote_secondary
–enable-lazy-preload
socket的名称:zygote_secondary
对应的代码入口为:frameworks/base/cmds/app_process/app_main.cpp

Zygote启动后做了什么

init进程通过init.zygote64_32.rc来调用/system/bin/app_process64 来启动zygote进程,入口app_main.cpp
frameworks/base/cmds/app_process/app_main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
int main(int argc, char* const argv[])
{
/*
zygote传入的参数是:
-Xzygote
/system/bin
--zygote
--start-system-server
--socket-name=zygote

zygote_secondary传入的参数是:
-Xzygote
/system/bin
--zygote
--socket-name=zygote_secondary
--enable-lazy-preload
*/

......

// Parse runtime arguments. Stop at first unrecognized option.
bool zygote = false;
bool startSystemServer = false;
bool application = false;
String8 niceName;
String8 className;

++i; // Skip unused "parent dir" argument.
while (i < argc) {
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) {
zygote = true;
//对于64位系统nice_name为zygote64,32位系统为zygote
niceName = ZYGOTE_NICE_NAME;
} else if (strcmp(arg, "--start-system-server") == 0) {
//是否需要启动system server
startSystemServer = true;
} else if (strcmp(arg, "--application") == 0) {
//启动进入独立的程序模式
application = true;
} else if (strncmp(arg, "--nice-name=", 12) == 0) {
//niceName为当前进程别名,区别abi型号
niceName.setTo(arg + 12);
} else if (strncmp(arg, "--", 2) != 0) {
className.setTo(arg);
break;
} else {
--i;
break;
}
}

Vector<String8> args;
if (!className.isEmpty()) {//className不为空,说明是application启动模式
// We're not in zygote mode, the only argument we need to pass
// to RuntimeInit is the application argument.
//
// The Remainder of args get passed to startup class main(). Make
// copies of them before we overwrite them with the process name.
args.add(application ? String8("application") : String8("tool"));
runtime.setClassNameAndArgs(className, argc - i, argv + i);

if (!LOG_NDEBUG) {
String8 restOfArgs;
char* const* argv_new = argv + i;
int argc_new = argc - i;
for (int k = 0; k < argc_new; ++k) {
restOfArgs.append("\"");
restOfArgs.append(argv_new[k]);
restOfArgs.append("\" ");
}
ALOGV("Class name = %s, args = %s", className.string(), restOfArgs.string());
}
} else {
// We're in zygote mode.
//进入zygote模式
//新建Dalvik的缓存目录:/data/dalvik-cache
maybeCreateDalvikCache();

if (startSystemServer) {
//添加start-system-server参数
args.add(String8("start-system-server"));
}

char prop[PROP_VALUE_MAX];
if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) {
LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.",
ABI_LIST_PROPERTY);
return 11;
}

String8 abiFlag("--abi-list=");
abiFlag.append(prop);
//添加--abi-list=参数
args.add(abiFlag);

// In zygote mode, pass all remaining arguments to the zygote
// main() method.
for (; i < argc; ++i) {
//将剩下的参数加入args
args.add(String8(argv[i]));
}
}

//设置一个“好听的昵称” zygote\zygote64,之前的名称是app_process
if (!niceName.isEmpty()) {
runtime.setArgv0(niceName.string(), true /* setProcName */);
}

if (zygote) {
//如果是zygote启动模式,则加载ZygoteInit
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {
//如果是application启动模式,则加载RuntimeInit
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
} else {
//没有指定类名或zygote,参数错误
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
app_usage();
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
}
}

Zygote本身是一个Native的应用程序,刚开始的进程名称为“app_process”,运行过程中,通过调用setArgv0将名字改为zygote 或者 zygote64(根据操作系统而来),最后通过runtime的start()方法来真正的加载虚拟机并进入JAVA世界。
在app_main.cpp的最后调用了runtime.start()方法,runtime是AppRuntime的对象,AppRuntime是AndroidRuntime的子类,
进入到AndroidRuntime.cpp#start()
frameworks/base/core/jni/AndroidRuntime.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
ALOGD(">>>>>> START %s uid %d <<<<<<\n",
className != NULL ? className : "(unknown)", getuid());

static const String8 startSystemServer("start-system-server");
// Whether this is the primary zygote, meaning the zygote which will fork system server.
bool primary_zygote = false;

......

/* start the virtual machine */
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;

//启动虚拟机,主要是关于虚拟机参数的设置
if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
return;
}
onVmCreated(env);//空函数,没有任何实现

/*
* Register android functions.
*/
//注册JNI方法
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}

/*
* We want to call main() with a String array with arguments in it.
* At present we have two arguments, the class name and an option string.
* Create an array to hold them.
*/
jclass stringClass;
jobjectArray strArray;
jstring classNameStr;

stringClass = env->FindClass("java/lang/String");
assert(stringClass != NULL);
//等价 strArray[0] = "com.android.internal.os.ZygoteInit"
strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
assert(strArray != NULL);
classNameStr = env->NewStringUTF(className);
assert(classNameStr != NULL);
env->SetObjectArrayElement(strArray, 0, classNameStr);

//strArray[1]="start-system-server";
//strArray[2]="--abi-list=xxx";
//其中xxx为系统响应的cpu架构类型,比如arm64-v8a
for (size_t i = 0; i < options.size(); ++i) {
jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());
assert(optionsStr != NULL);
env->SetObjectArrayElement(strArray, i + 1, optionsStr);
}

/*
* Start VM. This thread becomes the main thread of the VM, and will
* not return until the VM exits.
*/
//将"com.android.internal.os.ZygoteInit"转换为"com/android/internal/os/ZygoteInit"
char* slashClassName = toSlashClassName(className != NULL ? className : "");
jclass startClass = env->FindClass(slashClassName);//找到Zygoteinit
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} else {
//找到这个类后,继续找成员函数main方法的Method ID
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
/* keep going */
} else {
//通过反射调用ZygoteInit.main()方法
env->CallStaticVoidMethod(startClass, startMeth, strArray);

#if 0
if (env->ExceptionCheck())
threadExitUncaughtException(env);
#endif
}
}
//释放相应对象的内存空间
free(slashClassName);

ALOGD("Shutting down VM\n");
if (mJavaVM->DetachCurrentThread() != JNI_OK)
ALOGW("Warning: unable to detach main thread\n");
if (mJavaVM->DestroyJavaVM() != 0)
ALOGW("Warning: VM did not shut down cleanly\n");
}

在start()方法中主要完成了:

  1. 调用startVm开启虚拟机,主要是配置虚拟机的相关参数
  2. 调用startReg注册JNI方法
  3. 使用JNI把Zyogte进程启动

在start()方法的最后用来反射调用了ZygoteInit的main函数,Zygote便进入了Java框架层。
进入到ZygoteInit.java#main()
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
public static void main(String[] argv) {
//1.创建ZygoteServer
ZygoteServer zygoteServer = null;

// Mark zygote start. This ensures that thread creation will throw
// an error.
//调用native函数,确保当前没有其它线程在运行
ZygoteHooks.startZygoteNoThreadCreation();

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

Runnable caller;
try {
// Store now for StatsLogging later.
final long startTime = SystemClock.elapsedRealtime();
final boolean isRuntimeRestarted = "1".equals(
SystemProperties.get("sys.boot_completed"));

//得到systrace的监控TAG
String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag,
Trace.TRACE_TAG_DALVIK);
//通过systrace来追踪函数ZygoteInit,可以通过systrace工具来进行分析
//traceBegin和traceEnd要成对出现,而且需要使用同一个tag
bootTimingsTraceLog.traceBegin("ZygoteInit");
//开启DDMS(Dalvik Debug Monitor Service)功能
//注册所有已知的Java VM的处理块的监听器。线程监听、内存监听、native 堆内存监听、debug模式监听等等
RuntimeInit.preForkInit();

boolean startSystemServer = false;
String zygoteSocketName = "zygote";
String abiList = null;
boolean enableLazyPreload = false;

//2.解析app_main.cpp#start()传入的参数
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;//启动zygote时,才会传入参数:start-system-server
} else if ("--enable-lazy-preload".equals(argv[i])) {
enableLazyPreload = true;//启动zygote_secondary时,才会传入参数:enable-lazy-preload
} else if (argv[i].startsWith(ABI_LIST_ARG)) {
abiList = argv[i].substring(ABI_LIST_ARG.length());//通过属性ro.product.cpu.abilist64\ro.product.cpu.abilist32 从C空间传来的值
} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());//会有两种值:zygote和zygote_secondary
} else {
throw new RuntimeException("Unknown command line argument: " + argv[i]);
}
}

//根据传入socket name来决定是创建zygote还是zygote_secondary
final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME);

if (!isRuntimeRestarted) {
if (isPrimaryZygote) {
FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__ZYGOTE_INIT_START,
startTime);
} else if (zygoteSocketName.equals(Zygote.SECONDARY_SOCKET_NAME)) {
FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__SECONDARY_ZYGOTE_INIT_START,
startTime);
}
}

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.
// 在第一次zygote启动时,enableLazyPreload为false,执行preload
if (!enableLazyPreload) {
//systrace 追踪 ZygotePreload
bootTimingsTraceLog.traceBegin("ZygotePreload");
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
/// M: Added for BOOTPROF
addBootEvent("Zygote:Preload Start");
/// @}
// 3.加载进程的资源和类
preload(bootTimingsTraceLog);
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
//systrace结束 ZygotePreload的追踪
bootTimingsTraceLog.traceEnd(); // ZygotePreload
}

// Do an initial gc to clean up after startup
bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
gcAndFinalize();
bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC

//结束ZygoteInit的systrace追踪
bootTimingsTraceLog.traceEnd(); // ZygoteInit

Zygote.initNativeState(isPrimaryZygote);

/// M: Added for BOOTPROF
addBootEvent("Zygote:Preload End");
/// @}
ZygoteHooks.stopZygoteNoThreadCreation();

// 4.调用ZygoteServer 构造函数,创建socket,会根据传入的参数
// 创建两个socket:/dev/socket/zygote 和 /dev/socket/zygote_secondary
zygoteServer = new ZygoteServer(isPrimaryZygote);

if (startSystemServer) {
//5.fork出SystemServer
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);

// {@code r == null} in the parent (zygote) process, and {@code r != null} in the
// child (system_server) process.
//启动SystemServer
if (r != null) {
r.run();
return;
}
}

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.
//6.zygote进程进入无限循环,处理请求
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with fatal exception", ex);
throw ex;
} finally {
if (zygoteServer != null) {
zygoteServer.closeServerSocket();
}
}

// We're in the child process and have exited the select loop. Proceed to execute the
// command.
if (caller != null) {
caller.run();
}
}

总结zygoteInit.java#main()完成了:

  1. 创建ZygoteServer
  2. 解析了从app_main.cpp#start()传入的参数
  3. 加载进程的资源和类
  4. 调用ZygoteServer构造函数,创建sokect
  5. fork出SystemServer
  6. zygote进程进入无限循环,处理请求

进入到ZygoteInit.java#preload()预加载

预加载是指在zygote进程启动的时候就加载,这样系统只在zygote执行一次加载操作,所有APP用到该资源不需要再重新加载,减少资源加载时间,加快了应用启动速度,一般情况下,系统中App共享的资源会被列为预加载资源。
zygote fork子进程时,根据fork的copy-on-write(写时拷贝)机制可知,有些类如果不做改变,甚至都不用复制,子进程可以和父进程共享这部分数据,从而省去不少内存的占用。
预加载的原理:
zygote进程启动后将资源读取出来,保存到Resources一个全局静态变量中,下次读取系统资源的时候优先从静态变量中查找。
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
static void preload(TimingsTraceLog bootTimingsTraceLog) {
Log.d(TAG, "begin preload");
bootTimingsTraceLog.traceBegin("BeginPreload");
beginPreload();//获取字符集转换资源等
bootTimingsTraceLog.traceEnd(); // BeginPreload
bootTimingsTraceLog.traceBegin("PreloadClasses");
//预加载类的列表---/system/etc/preloaded-classes, 在/frameworks/base/config/preloaded-classes 中,Android10.0中预计有7603左右个类
preloadClasses();
bootTimingsTraceLog.traceEnd(); // PreloadClasses
bootTimingsTraceLog.traceBegin("CacheNonBootClasspathClassLoaders");
cacheNonBootClasspathClassLoaders();
bootTimingsTraceLog.traceEnd(); // CacheNonBootClasspathClassLoaders
bootTimingsTraceLog.traceBegin("PreloadResources");
//加载图片、颜色等资源文件,部分定义在 /frameworks/base/core/res/res/values/arrays.xml中
preloadResources();
bootTimingsTraceLog.traceEnd(); // PreloadResources
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs");
nativePreloadAppProcessHALs();
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadGraphicsDriver");
maybePreloadGraphicsDriver();
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
// 加载 android、compiler_rt、jnigraphics等library
preloadSharedLibraries();
//用于初始化文字资源
preloadTextResources();
// Ask the WebViewFactory to do any initialization that must run in the zygote process,
// for memory sharing purposes.
//用于初始化webview;
WebViewFactory.prepareWebViewInZygote();
//预加载完成,可以查看下面的log
endPreload();
warmUpJcaProviders();
Log.d(TAG, "end preload");

sPreloadComplete = true;
}

进入到ZygoteServer.java#ZygoteServer(boolean isPrimaryZygote)
说明:ZygoteServer 构造函数初始化时,根据传入的参数,利用LocalServerSocket (createManagedSocketFromInitSocket()方法中调用)创建了1个本地服务端的socket,用来建立连接。
frameworks/base/core/java/com/android/internal/os/ZygoteServer.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//创建zygote的socket
ZygoteServer(boolean isPrimaryZygote) {
mUsapPoolEventFD = Zygote.getUsapPoolEventFD();

if (isPrimaryZygote) {
//创建socket,并获取socket对象,socketname:zygote
mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.PRIMARY_SOCKET_NAME);
mUsapPoolSocket =
Zygote.createManagedSocketFromInitSocket(
Zygote.USAP_POOL_PRIMARY_SOCKET_NAME);
} else {
//socketname:zygote_secondary
mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.SECONDARY_SOCKET_NAME);
mUsapPoolSocket =
Zygote.createManagedSocketFromInitSocket(
Zygote.USAP_POOL_SECONDARY_SOCKET_NAME);
}

mUsapPoolSupported = true;
fetchUsapPoolPolicyProps();
}

进入到ZygoteInit.java#forkSystemServer()
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
long capabilities = posixCapabilitiesAsBits(
OsConstants.CAP_IPC_LOCK,
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_PTRACE,
OsConstants.CAP_SYS_TIME,
OsConstants.CAP_SYS_TTY_CONFIG,
OsConstants.CAP_WAKE_ALARM,
OsConstants.CAP_BLOCK_SUSPEND
);
....
//准备参数
/* 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,1023,"
+ "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010,3011",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
"com.android.server.SystemServer",
};
ZygoteArguments parsedArgs;

int pid;

try {
ZygoteCommandBuffer commandBuffer = new ZygoteCommandBuffer(args);
try {
//将上面准备的参数,按照ZygoteArguments的风格进行封装
parsedArgs = ZygoteArguments.getInstance(commandBuffer);
} catch (EOFException e) {
throw new AssertionError("Unexpected argument error for forking system server", e);
}
commandBuffer.close();
Zygote.applyDebuggerSystemProperty(parsedArgs);
Zygote.applyInvokeWithSystemProperty(parsedArgs);

.....
//通过fork“分裂”出子进程system_server
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.mUid, parsedArgs.mGid,
parsedArgs.mGids,
parsedArgs.mRuntimeFlags,
null,
parsedArgs.mPermittedCapabilities,
parsedArgs.mEffectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}

//进入子进程system_server
/* For child process */
if (pid == 0) {
// 处理32_64和64_32的情况
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
// fork时会copy socket,system server需要主动关闭
zygoteServer.closeServerSocket();
// system server进程处理自己的工作
return handleSystemServerProcess(parsedArgs);
}

return null;
}

主要时调用了Zygote.java#forkSystemServer()方法,在这个方法中调用了Native的方法,但最后会调用fork()方法创建子进程。
fork()函数得到的子进程是父进程的一个复制品,通过写时拷贝实现。
fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次。
返回值:

  • 返回0:表示成功创建子进程,并且接下来进入子进程执行liuc
  • 返回>0:表示成功创建子进程,并且急促执行父进程流程代码
  • 返回非正数<0:表示创建子进程失败,失败的原因主要有:进程数超过了系统所能创建的上线,errno会被设置为EAGAIN系统内存不足,errno会被设置为ENOMEM

回到ZygoteServer()方法中,在新fork出的子进程中调用了handleSystemServerProcess(),主要是返回Runtime.java的MethodAndArgsCaller的方法,然后通过r.run() 启动com.android.server.SystemServer的main 方法。
这个当我们后面的SystemServer的章节进行详细讲解。
handleSystemServerProcess代码流程:

1
2
3
4
5
6
7
8
9
10
11
handleSystemServerProcess()
|
[ZygoteInit.java]
zygoteInit()
|
[RuntimeInit.java]
applicationInit()
|
findStaticMain()
|
MethodAndArgsCaller()

进入ZygoteServer.java#runSelectLoop()
说明:使zygote进程进入无限循环,处理请求
frameworks/base/core/java/com/android/internal/os/ZygoteServer.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
Runnable runSelectLoop(String abiList) {
ArrayList<FileDescriptor> socketFDs = new ArrayList<>();
ArrayList<ZygoteConnection> peers = new ArrayList<>();

//将server socket加入到fds
socketFDs.add(mZygoteSocket.getFileDescriptor());
peers.add(null);

mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP;

while (true) {
fetchUsapPoolPolicyPropsWithMinInterval();
mUsapPoolRefillAction = UsapPoolRefillAction.NONE;

int[] usapPipeFDs = null;
StructPollfd[] pollFDs;
//每次循环,都重新创建需要监听的pollFds
if (mUsapPoolEnabled) {
usapPipeFDs = Zygote.getUsapPipeFDs();
pollFDs = new StructPollfd[socketFDs.size() + 1 + usapPipeFDs.length];
} else {
pollFDs = new StructPollfd[socketFDs.size()];
}

int pollIndex = 0;
for (FileDescriptor socketFD : socketFDs) {
//关注事件到来
pollFDs[pollIndex] = new StructPollfd();
pollFDs[pollIndex].fd = socketFD;
pollFDs[pollIndex].events = (short) POLLIN;
++pollIndex;
}

final int usapPoolEventFDIndex = pollIndex;

if (mUsapPoolEnabled) {
pollFDs[pollIndex] = new StructPollfd();
pollFDs[pollIndex].fd = mUsapPoolEventFD;
pollFDs[pollIndex].events = (short) POLLIN;
++pollIndex;

// The usapPipeFDs array will always be filled in if the USAP Pool is enabled.
assert usapPipeFDs != null;
for (int usapPipeFD : usapPipeFDs) {
FileDescriptor managedFd = new FileDescriptor();
managedFd.setInt$(usapPipeFD);

pollFDs[pollIndex] = new StructPollfd();
pollFDs[pollIndex].fd = managedFd;
pollFDs[pollIndex].events = (short) POLLIN;
++pollIndex;
}
}

int pollTimeoutMs;

if (mUsapPoolRefillTriggerTimestamp == INVALID_TIMESTAMP) {
pollTimeoutMs = -1;
} else {
long elapsedTimeMs = System.currentTimeMillis() - mUsapPoolRefillTriggerTimestamp;

if (elapsedTimeMs >= mUsapPoolRefillDelayMs) {
// The refill delay has elapsed during the period between poll invocations.
// We will now check for any currently ready file descriptors before refilling
// the USAP pool.
pollTimeoutMs = 0;
mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP;
mUsapPoolRefillAction = UsapPoolRefillAction.DELAYED;

} else if (elapsedTimeMs <= 0) {
// This can occur if the clock used by currentTimeMillis is reset, which is
// possible because it is not guaranteed to be monotonic. Because we can't tell
// how far back the clock was set the best way to recover is to simply re-start
// the respawn delay countdown.
pollTimeoutMs = mUsapPoolRefillDelayMs;

} else {
pollTimeoutMs = (int) (mUsapPoolRefillDelayMs - elapsedTimeMs);
}
}

int pollReturnValue;
try {
//等待事件到来
pollReturnValue = Os.poll(pollFDs, pollTimeoutMs);
} catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex);
}

if (pollReturnValue == 0) {
// The poll returned zero results either when the timeout value has been exceeded
// or when a non-blocking poll is issued and no FDs are ready. In either case it
// is time to refill the pool. This will result in a duplicate assignment when
// the non-blocking poll returns zero results, but it avoids an additional
// conditional in the else branch.
mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP;
mUsapPoolRefillAction = UsapPoolRefillAction.DELAYED;

} else {
boolean usapPoolFDRead = false;
//倒序处理,即优先处理已建立链接的信息,后处理新建链接的请求
while (--pollIndex >= 0) {
if ((pollFDs[pollIndex].revents & POLLIN) == 0) {
continue;
}

//server socket最先加入fds,因此这里是server socket收到数据
if (pollIndex == 0) {
// Zygote server socket
//收到新的建立通信的请求,建立通信连接
ZygoteConnection newPeer = acceptCommandPeer(abiList);
//加入到peers和fds,即下一次也开监听
peers.add(newPeer);
socketFDs.add(newPeer.getFileDescriptor());
} else if (pollIndex < usapPoolEventFDIndex) {
// Session socket accepted from the Zygote server socket
//说明接收AMS发送过来创建应用程序的请求,调用processOneCommand来创建新的应用程序进程
try {
//有socket连接,创建ZygoteConnection对象,并添加到fds
ZygoteConnection connection = peers.get(pollIndex);
boolean multipleForksOK = !isUsapPoolEnabled()
&& ZygoteHooks.isIndefiniteThreadSuspensionSafe();
//处理连接
final Runnable command =
connection.processCommand(this, multipleForksOK);

// TODO (chriswailes): Is this extra check necessary?
if (mIsForkChild) {
// We're in the child. We should always have a command to run at
// this stage if processCommand hasn't called "exec".
if (command == null) {
throw new IllegalStateException("command == null");
}

return command;
} else {
// We're in the server - we should never have any commands to run.
if (command != null) {
throw new IllegalStateException("command != null");
}

// We don't know whether the remote side of the socket was closed or
// not until we attempt to read from it from processCommand. This
// shows up as a regular POLLIN event in our regular processing
// loop.
if (connection.isClosedByPeer()) {
connection.closeSocket();
peers.remove(pollIndex);
socketFDs.remove(pollIndex);//处理完则从fds中移除该文件描述符
}
}
} catch (Exception e) {
......
} finally {
// Reset the child flag, in the event that the child process is a child-
// zygote. The flag will not be consulted this loop pass after the
// Runnable is returned.
mIsForkChild = false;
}

}
......
}

processOneCommand()
frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Runnable processCommand(ZygoteServer zygoteServer, boolean multipleOK) {
.....
if (parsedArgs.mInvokeWith != null || parsedArgs.mStartChildZygote
|| !multipleOK || peer.getUid() != Process.SYSTEM_UID) {
// Continue using old code for now. TODO: Handle these cases in the other path.
//fork子进程
pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid,
parsedArgs.mGids, parsedArgs.mRuntimeFlags, rlimits,
parsedArgs.mMountExternal, parsedArgs.mSeInfo, parsedArgs.mNiceName,
fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
parsedArgs.mInstructionSet, parsedArgs.mAppDataDir,
parsedArgs.mIsTopApp, parsedArgs.mPkgDataInfoList,
parsedArgs.mAllowlistedDataInfoList, parsedArgs.mBindMountAppDataDirs,
parsedArgs.mBindMountAppStorageDirs);

try {
if (pid == 0) {
// in child
//子进程执行
zygoteServer.setForkChild();

zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
//进入子进程流程
return handleChildProc(parsedArgs, childPipeFd,
parsedArgs.mStartChildZygote);
} else {
// In the parent. A pid < 0 indicates a failure and will be handled in
// handleParentProc.
//父进程执行
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
handleParentProc(pid, serverPipeFd);
return null;
}
}
.....
}

handleChildProc()
frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
private Runnable handleChildProc(ZygoteArguments parsedArgs,
FileDescriptor pipeFd, boolean isZygote) {

closeSocket();

Zygote.setAppProcessName(parsedArgs, TAG);

// End of the postFork event.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
if (parsedArgs.mInvokeWith != null) {
WrapperInit.execApplication(parsedArgs.mInvokeWith,
parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
VMRuntime.getCurrentInstructionSet(),
pipeFd, parsedArgs.mRemainingArgs);

// Should not get here.
throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
} else {
if (!isZygote) {
//App进程将会调用到这里,执行目标类的main()方法
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mDisabledCompatChanges,
parsedArgs.mRemainingArgs, null /* classLoader */);
} else {
return ZygoteInit.childZygoteInit(
parsedArgs.mRemainingArgs /* classLoader */);
}
}
}

总结

  1. 开启虚拟器
  2. 注册了JNI
  3. 通过JNI调用ZygoteInit的main函数进入Zygote的Java框架层
  4. 创建了服务端Socket
  5. 预加载类和资源
  6. 启动SystemServer进程
  7. 通过runSelectLoop函数无限循环等待如AMS等的请求
本文链接:
http://longzhiye.top/2024/03/02/2024-03-02/