聊聊 "进程" 如何 "创建"

Updated on 2020.03.27

关键类 路径
app_main.java frameworks/base/cmds/app_process/app_main.cpp
com_android_internal_os_Zygote.cpp frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
dalvik_system_ZygoteHooks.cc art/runtime/native/dalvik_system_ZygoteHooks.cc
fork.cpp bionic/libc/bionic/fork.cpp
runtime.cc art/runtime/runtime.cc
ActivityThread.java frameworks/base/core/java/android/app/ActivityThread.java
AndroidRuntime.cpp frameworks/base/core/jni/AndroidRuntime.cpp
Daemons.java libcore/libart/src/main/java/java/lang/Daemons.java
Process.java frameworks/base/core/java/android/os/Process.java
RuntimeInit.java frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
Zygote.java frameworks/base/core/java/com/android/internal/os/Zygote.java
ZygoteConnection.java frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
ZygoteHooks.java libcore/dalvik/src/main/java/dalvik/system/ZygoteHooks.java
ZygoteInit.java frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
ZygoteProcess.java frameworks/base/core/java/android/os/ZygoteProcess.java
ZygoteServer.java frameworks/base/core/java/com/android/internal/os/ZygoteServer.java

# 概述

说起 “进程”,很多人都会想到 “线程”,我们在具体分析之前,先了解一下“进程”和“线程”之间的区别!

✎  进程:每个 App 在启动前必须先创建一个进程,该进程是由 Zygote fork 出来的,进程具有独立的资源空间,用于承载 App 上运行的各种 Activity/Service 等组件。进程对于上层应用来说是完全透明的,这也是 google 有意为之,让 App 程序都是运行在 Android Runtime。大多数情况一个 App 就运行在一个进程中,除非在 AndroidManifest.xml 中配置 Android:process 属性,或通过 native 代码 fork 进程。

✎  线程:线程对应用开发者来说非常熟悉,比如每次 new Thread().start() 都会创建一个新的线程,该线程并没有自己独立的地址空间,而是与其所在进程之间资源共享。从 Linux 角度来说进程与线程都是一个 task_struct 结构体,除了是否共享资源外,并没有其他本质的区别。

# 进程创建

进程创建.png


一、system_server

首先探讨 system_server 发起请求的源码流程:

1.1 Process.start

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// frameworks/base/core/java/android/os/Process.java

public static final ProcessStartResult start(final String processClass, final String niceName,
int uid, int gid, int[] gids,
int runtimeFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String invokeWith,
String[] zygoteArgs) {
return zygoteProcess.start(processClass, niceName, uid, gid, gids, runtimeFlags,
mountExternal, targetSdkVersion, seInfo, abi, instructionSet,
appDataDir, invokeWith, zygoteArgs);
}

1.2 ZygoteProcess.start

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// frameworks/base/core/java/android/os/ZygoteProcess.java

public final Process.ProcessStartResult start(final String processClass, final String niceName,
int uid, int gid, int[] gids,
int runtimeFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String invokeWith,
String[] zygoteArgs) {
try {
return startViaZygote(processClass, niceName, uid, gid, gids, runtimeFlags, mountExternal,
targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith,
false /* startChildZygote */, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
Log.e(LOG_TAG, "Starting VM process through Zygote failed");
throw new RuntimeException("Starting VM process through Zygote failed", ex);
}
}

1.3 startViaZygote

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
// frameworks/base/core/java/android/os/ZygoteProcess.java

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,
boolean startChildZygote,
String[] extraArgs)
throws ZygoteStartFailedEx {
// 生成 argsForZygote 数组,该数组保存了进程的 uid、gid、groups、target-sdk 等一系列的参数
ArrayList<String> argsForZygote = new ArrayList<String>();

argsForZygote.add("--runtime-args");
argsForZygote.add("--setuid=" + uid);
argsForZygote.add("--setgid=" + gid);
argsForZygote.add("--runtime-flags=" + runtimeFlags);
... ...
argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
... ...

synchronized(mLock) {
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
}

1.4 openZygoteSocketIfNeeded

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
// frameworks/base/core/java/android/os/ZygoteProcess.java

private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
Preconditions.checkState(Thread.holdsLock(mLock), "ZygoteProcess lock not held");

if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
try {
// 向主 zygote 发起 connect() 操作
primaryZygoteState = ZygoteState.connect(mSocket);
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
}
maybeSetApiBlacklistExemptions(primaryZygoteState, false);
maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
}
if (primaryZygoteState.matches(abi)) {
return primaryZygoteState;
}

if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
try {
// 当主 zygote 没能匹配成功,则采用第二个 zygote,发起 connect() 操作
secondaryZygoteState = ZygoteState.connect(mSecondarySocket);
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);
}
maybeSetApiBlacklistExemptions(secondaryZygoteState, false);
maybeSetHiddenApiAccessLogSampleRate(secondaryZygoteState);
}

if (secondaryZygoteState.matches(abi)) {
return secondaryZygoteState;
}

throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
}

openZygoteSocketIfNeeded(abi) 方法是根据当前的 abi 来选择与 zygote 还是 zygote64 来进行通信。

1.5 zygoteSendArgsAndGetResult

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
// frameworks/base/core/java/android/os/ZygoteProcess.java

private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, ArrayList<String> args)
throws ZygoteStartFailedEx {
try {
int sz = args.size();
for (int i = 0; i < sz; i++) {
if (args.get(i).indexOf('\n') >= 0) {
throw new ZygoteStartFailedEx("embedded newlines not allowed");
}
}

final BufferedWriter writer = zygoteState.writer;
final DataInputStream inputStream = zygoteState.inputStream;

writer.write(Integer.toString(args.size()));
writer.newLine();

for (int i = 0; i < sz; i++) {
String arg = args.get(i);
writer.write(arg);
writer.newLine();
}

writer.flush();

Process.ProcessStartResult result = new Process.ProcessStartResult();

// 等待 socket 服务端(即 zygote)返回新创建的进程 pid;
result.pid = inputStream.readInt();
result.usingWrapper = inputStream.readBoolean();

if (result.pid < 0) {
throw new ZygoteStartFailedEx("fork() failed");
}
return result;
} catch (IOException ex) {
zygoteState.close();
throw new ZygoteStartFailedEx(ex);
}
}

这个方法的定义就说明了它的含义,主要功能是通过 socket 通道向 Zygote 进程发送一个”参数列表”,然后进入”阻塞等待”状态,直到远端的 socket 服务端发送回来新创建的进程 pid 才返回。

既然 system_server 进程的 zygoteSendArgsAndGetResult() 方法通过 socketZygote 进程发送消息,这时便会唤醒 Zygote 进程,来响应 socket 客户端的请求(即 system_server 端),接下来的操作便是在 Zygote 来创建进程。

1.6 源码流程图(system_server)

源码流程图.png


二、Zygote

我们都知道 Zygote 进程是由 init 进程创建的,进程启动之后便会调用 ZygoteInit.main() 方法,经过创建 socket 管道,预加载资源后,调用 runSelectLoop()方法。

2.1 main

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

public static void main(String argv[]) {
... ...
try {
... ...
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
... ...
}

if (caller != null) {
caller.run();
}
}

2.2 runSelectLoop

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
// frameworks/base/core/java/com/android/internal/os/ZygoteServer.java

Runnable runSelectLoop(String abiList) {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();

// mServerSocket 是 socket 通信中的服务端,即 zygote 进程,保存到 fds[0]
fds.add(mServerSocket.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 {
// 处理轮询状态,当 pollFds 有事件到来则往下执行,否则阻塞在这里
Os.poll(pollFds, -1);
} catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex);
}
for (int i = pollFds.length - 1; i >= 0; --i) {
// 采用 I/O 多路复用机制,当接收到客户端发出连接请求或者数据处理请求到来,则往下执行;
// 否则进入 continue,跳出本次循环。
if ((pollFds[i].revents & POLLIN) == 0) {
continue;
}

if (i == 0) {
// 即 fds[0],代表的是 mServerSocket,则意味着有客户端连接请求;
// 创建 ZygoteConnection 对象,并添加到 fds。
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
try {
// i > 0,则代表通过 socket 接收来自对端的数据,并执行相应操作
ZygoteConnection connection = peers.get(i);
final Runnable command = connection.processOneCommand(this);
... ...
} catch (Exception e) {
... ...
}
}
}
}
}

2.3 acceptCommandPeer

1
2
3
4
5
6
7
8
9
10
// frameworks/base/core/java/com/android/internal/os/ZygoteServer.java

private ZygoteConnection acceptCommandPeer(String abiList) {
try {
// 接收客户端发送过来的 connect() 操作,Zygote 作为服务端执行 accept() 操作
return createNewConnection(mServerSocket.accept(), abiList);
} catch (IOException ex) {
throw new RuntimeException("IOException during accept()", ex);
}
}

没有连接请求时会进入休眠状态,当有创建新进程的连接请求时,唤醒 Zygote 进程,创建 Socket 通道 ZygoteConnection,然后执行 ZygoteConnection 的 processOneCommand() 方法。

2.4 processOneCommand

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
// frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java

Runnable processOneCommand(ZygoteServer zygoteServer) {
String args[];
Arguments parsedArgs = null;
FileDescriptor[] descriptors;

try {
args = readArgumentList(); // 读取 socket 客户端发送过来的参数列表
descriptors = mSocket.getAncillaryFileDescriptors();
} catch (IOException ex) {
throw new IllegalStateException("IOException on command socket", ex);
}
... ...
int pid = -1;
FileDescriptor childPipeFd = null;
FileDescriptor serverPipeFd = null;

// 将 binder 客户端传递过来的参数,解析成 Arguments 对象格式
parsedArgs = new Arguments(args);
... ...
int [] fdsToClose = { -1, -1 };

FileDescriptor fd = mSocket.getFileDescriptor();

if (fd != null) {
fdsToClose[0] = fd.getInt$();
}
fd = zygoteServer.getServerSocketFileDescriptor();
if (fd != null) {
fdsToClose[1] = fd.getInt$();
}

fd = null;

// forkAndSpecialize 为重点方法
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.startChildZygote,
parsedArgs.instructionSet, parsedArgs.appDataDir);

try {
if (pid == 0) {
// in child
zygoteServer.setForkChild();

zygoteServer.closeServerSocket();
// 子进程执行
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;

// App 进程创建完成后(fork 成功后),会执行此方法
return handleChildProc(parsedArgs, descriptors, childPipeFd, parsedArgs.startChildZygote);
} else {
// 父进程执行
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
handleParentProc(pid, descriptors, serverPipeFd);
return null;
}
} finally {
IoUtils.closeQuietly(childPipeFd);
IoUtils.closeQuietly(serverPipeFd);
}
}

2.5 forkAndSpecialize

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
// frameworks/base/core/java/com/android/internal/os/Zygote.java

public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir) {
// private static final ZygoteHooks VM_HOOKS = new ZygoteHooks();
// VM_HOOKS 是 Zygote 对象的静态成员变量
VM_HOOKS.preFork();

// Resets nice priority for zygote process.
resetNicePriority();

// 重点方法
int pid = nativeForkAndSpecialize(
uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
fdsToIgnore, startChildZygote, instructionSet, appDataDir);

// Enable tracing as soon as possible for the child process.
if (pid == 0) {
Trace.setTracingEnabled(true, runtimeFlags);

// Note that this event ends at the end of handleChildProc,
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
}
VM_HOOKS.postForkCommon();
eturn pid;
}

2.6 preFork

1
2
3
4
5
6
7
// libcore/dalvik/src/main/java/dalvik/system/ZygoteHooks.java

public void preFork() {
Daemons.stop(); // 停止 4 个 Daemon 子线程
waitUntilAllThreadsStopped(); // 等待所有子线程结束
token = nativePreFork(); // 完成 gc 堆的初始化工作
}

2.6.1 Daemons.stop

1
2
3
4
5
6
7
8
// libcore/libart/src/main/java/java/lang/Daemons.java

public static void stop() {
HeapTaskDaemon.INSTANCE.stop(); // Java 堆整理线程
ReferenceQueueDaemon.INSTANCE.stop(); // 引用队列线程
FinalizerDaemon.INSTANCE.stop(); // 析构线程
FinalizerWatchdogDaemon.INSTANCE.stop(); // 析构监控线程
}

2.6.2 waitUntilAllThreadsStopped

1
2
3
4
5
6
7
8
9
// libcore/dalvik/src/main/java/dalvik/system/ZygoteHooks.java

private static void waitUntilAllThreadsStopped() {
File tasks = new File("/proc/self/task");
// 当 /proc 中线程数大于 1,就出让 CPU 直到只有一个线程,才退出循环
while (tasks.list().length > 1) {
Thread.yield();
}
}

2.6.3 nativePreFork

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
// libcore/dalvik/src/main/java/dalvik/system/ZygoteHooks.java

private static native long nativePreFork();
}

// art/runtime/native/dalvik_system_ZygoteHooks.cc

static jlong ZygoteHooks_nativePreFork(JNIEnv* env, jclass) {
Runtime* runtime = Runtime::Current();
CHECK(runtime->IsZygote()) << "runtime instance not started with -Xzygote";

// 执行 PreZygoteFork 函数
runtime->PreZygoteFork();

if (Trace::GetMethodTracingMode() != TracingMode::kTracingInactive) {
// Tracing active, pause it.
Trace::Pause();
}

// 将线程转换为 long 型并保存到 token,该过程是非安全的
return reinterpret_cast<jlong>(ThreadForEnv(env));
}


// art/runtime/runtime.cc

void Runtime::PreZygoteFork() {
// 堆的初始化工作,这里就不继续再往下追 art 虚拟机
heap_->PreZygoteFork();
}

2.7 nativeForkAndSpecialize

接下来,我们跟踪 nativeForkAndSpecialize 的源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// frameworks/base/core/java/com/android/internal/os/Zygote.java

native private static int nativeForkAndSpecialize(int uid, int gid, int[] gids,int runtimeFlags,
int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir);

// frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
jint runtime_flags, jobjectArray rlimits,
jint mount_external, jstring se_info, jstring se_name,
jintArray fdsToClose, jintArray fdsToIgnore, jboolean is_child_zygote,
jstring instructionSet, jstring appDataDir) {
... ...
return ForkAndSpecializeCommon(env, uid, gid, gids, runtime_flags,
rlimits, capabilities, capabilities, mount_external, se_info,
se_name, false, fdsToClose, fdsToIgnore, is_child_zygote == JNI_TRUE,
instructionSet, appDataDir);
}

2.8 ForkAndSpecializeCommon

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
// frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,
runtime_flags, jobjectArray javaRlimits,
jlong permittedCapabilities, jlong effectiveCapabilities,
jint mount_external,
jstring java_se_info, jstring java_se_name,
bool is_system_server, jintArray fdsToClose,
jintArray fdsToIgnore, bool is_child_zygote,
jstring instructionSet, jstring dataDir) {
// 设置子进程的 signal 信号处理函数
SetSignalHandlers();
... ...
// fork 子线程
pid_t pid = fork();

// 进入子线程
if (pid == 0) {
PreApplicationInit();

// 关闭并清除文件描述符
if (!DetachDescriptors(env, fdsToClose, &error_msg)) {
fail_fn(error_msg);
}
... ...
// 对于非 system_server 子进程,则创建进程组
if (!is_system_server && getuid() == 0) {
int rc = createProcessGroup(uid, getpid());
if (rc != 0) {
if (rc == -EROFS) {
ALOGW("createProcessGroup failed, kernel missing CONFIG_CGROUP_CPUACCT?");
} else {
ALOGE("createProcessGroup(%d, %d) failed: %s", uid, pid, strerror(-rc));
}
}

std::string error_msg;
// 设置 group
if (!SetGids(env, javaGids, &error_msg)) {
fail_fn(error_msg);
}

// 设置资源 limit
if (!SetRLimits(env, javaRlimits, &error_msg)) {
fail_fn(error_msg);
}
... ...
int rc = setresgid(gid, gid, gid);
rc = setresuid(uid, uid, uid);
... ...
if (!SetCapabilities(permittedCapabilities, effectiveCapabilities, permittedCapabilities,
&error_msg)) {
fail_fn(error_msg);
}

// 设置调度策略
if (!SetSchedulerPolicy(&error_msg)) {
fail_fn(error_msg);
}
... ...
// selinux 上下文
rc = selinux_android_setcontext(uid, is_system_server, se_info_c_str, se_name_c_str);
... ...
if (se_name_c_str == NULL && is_system_server) {
se_name_c_str = "system_server";
}
if (se_name_c_str != NULL) {
SetThreadName(se_name_c_str);
}
... ...
// 在 Zygote 子进程中,设置信号 SIGCHLD 的处理器恢复为默认行为
UnsetChldSignalHandler();

// 等价于调用 zygote.callPostForkChildHooks()
env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, runtime_flags,
is_system_server, is_child_zygote, instructionSet);
... ...
} else if (pid > 0) {
// the parent process,进入父进程,即 Zygote 进程
... ...
}
return pid;
}

2.9 源码流程图(system_server)

函数调用关系流程图.png

2.10 fork

fork() 采用 copy on write 技术,这是 linux 创建进程的标准方法,调用一次,返回两次,返回值有 3 种类型。

        ✎  父进程中,fork 返回新创建的子进程的 pid;
        ✎  子进程中,fork 返回 0;
        ✎  当出现错误时,fork 返回负数。(当进程数超过上限或者系统内存不足时会出错)

fork() 的主要工作是寻找空闲的进程号 pid,然后从父进程拷贝进程信息,例如数据段和代码段,fork() 后子进程要执行的代码等。 Zygote 进程是所有 Android 进程的母体,包括 system_server 和各个 App 进程。zygote 利用 fork() 方法生成新进程,对于新进程 A 复用 Zygote 进程本身的资源,再加上新进程 A 相关的资源,构成新的应用进程 A。

我们来看看源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// bionic/libc/bionic/fork.cpp

int fork() {
__bionic_atfork_run_prepare();

pthread_internal_t* self = __get_thread();

int result = clone(nullptr,
nullptr,
(CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD),
nullptr,
nullptr,
nullptr,
&(self->tid));
if (result == 0) {
self->set_cached_pid(gettid());
__bionic_atfork_run_child(); // fork 完成执行子进程回调方法
} else {
__bionic_atfork_run_parent(); // fork 完成执行父进程回调方法
}
return result;
}

2.11 callPostForkChildHooks

1
2
3
4
5
6
7
// frameworks/base/core/java/com/android/internal/os/Zygote.java

private static void callPostForkChildHooks(int runtimeFlags, boolean isSystemServer,
boolean isZygote, String instructionSet) {
// 调用 ZygoteHooks.postForkChild()
VM_HOOKS.postForkChild(runtimeFlags, isSystemServer, isZygote, instructionSet);
}

2.12 postForkChild

1
2
3
4
5
6
7
8
// libcore/dalvik/src/main/java/dalvik/system/ZygoteHooks.java

public void postForkChild(int runtimeFlags, boolean isSystemServer, boolean isZygote,
String instructionSet) {
nativePostForkChild(token, runtimeFlags, isSystemServer, isZygote, instructionSet);
// 设置新进程 Random 随机数种子为当前系统时间
Math.setRandomSeedInternal(System.currentTimeMillis());
}

2.13 nativePostForkChild

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
// art/runtime/native/dalvik_system_ZygoteHooks.cc

static void ZygoteHooks_nativePostForkChild(JNIEnv* env,
jclass,
jlong token,
jint runtime_flags,
jboolean is_system_server,
jboolean is_zygote,
jstring instruction_set) {
DCHECK(!(is_system_server && is_zygote));

// 记录当前线程
Thread* thread = reinterpret_cast<Thread*>(token);
// 设置新进程的主线程 id
thread->InitAfterFork();
... ...
if (instruction_set != nullptr && !is_system_server) {
ScopedUtfChars isa_string(env, instruction_set);
InstructionSet isa = GetInstructionSetFromString(isa_string.c_str());
Runtime::NativeBridgeAction action = Runtime::NativeBridgeAction::kUnload;
if (isa != InstructionSet::kNone && isa != kRuntimeISA) {
action = Runtime::NativeBridgeAction::kInitialize;
}
Runtime::Current()->InitNonZygoteOrPostFork(
env, is_system_server, action, isa_string.c_str());
} else {
Runtime::Current()->InitNonZygoteOrPostFork(
env,
is_system_server,
Runtime::NativeBridgeAction::kUnload,
/*isa*/ nullptr,
profile_system_server);
}
}

2.14 InitNonZygoteOrPostFork

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
// art/runtime/runtime.cc

void Runtime::InitNonZygoteOrPostFork(
JNIEnv* env,
bool is_system_server,
NativeBridgeAction action,
const char* isa,
bool profile_system_server) {
is_zygote_ = false;

if (is_native_bridge_loaded_) {
switch (action) {
case NativeBridgeAction::kUnload:
UnloadNativeBridge(); // 卸载用于跨平台的桥连库
is_native_bridge_loaded_ = false;
break;

case NativeBridgeAction::kInitialize:
InitializeNativeBridge(env, isa); // 初始化用于跨平台的桥连库
break;
}
}

// 创建 Java 堆处理的线程池
heap_->CreateThreadPool();
//重置 gc 性能数据,以保证进程在创建之前的 GCs 不会计算到当前 app 上
heap_->ResetGcPerformanceInfo();
... ...
if (!safe_mode_ &&
(jit_options_->UseJitCompilation() || jit_options_->GetSaveProfilingInfo()) &&
jit_ == nullptr) {
// 当 flag 被设置,并且还没有创建 JIT 时,则创建 JIT
CreateJit();
}

StartSignalCatcher(); // 设置信号处理函数

ScopedObjectAccess soa(Thread::Current());
GetRuntimeCallbacks()->StartDebugger();
}

2.15 postForkCommon

1
2
3
4
5
// libcore/dalvik/src/main/java/dalvik/system/ZygoteHooks.java

public void postForkCommon() {
Daemons.startPostZygoteFork();
}

2.16 startPostZygoteFork

1
2
3
4
5
6
7
8
// libcore/libart/src/main/java/java/lang/Daemons.java

public static void startPostZygoteFork() {
ReferenceQueueDaemon.INSTANCE.startPostZygoteFork();
FinalizerDaemon.INSTANCE.startPostZygoteFork();
FinalizerWatchdogDaemon.INSTANCE.startPostZygoteFork();
HeapTaskDaemon.INSTANCE.startPostZygoteFork();
}

VM_HOOKS.postForkCommon 的主要功能是在 fork 新进程后,启动 Zygote 的 4 个 Daemon线程,java堆整理,引用队列,以及析构线程。

2.17 源码流程图(Zygote)

函数调用关系流程图.png

至此,App 进程已完成了创建的所有工作,接下来就是开始新创建的 App 进程的工作。

前面我们提到过:在 ZygoteConnection.processOneCommand 方法中,zygote 进程执行完 forkAndSpecialize() 后,新创建的 App 进程便进入 handleChildProc() 方法。


三、APP 进程

3.1 handleChildProc

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
// frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java

private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,
FileDescriptor pipeFd, boolean isZygote) {
// 关闭 Zygote 的 socket 两端的连接
closeSocket();
if (descriptors != null) {
try {
Os.dup2(descriptors[0], STDIN_FILENO);
Os.dup2(descriptors[1], STDOUT_FILENO);
Os.dup2(descriptors[2], STDERR_FILENO);

for (FileDescriptor fd: descriptors) {
IoUtils.closeQuietly(fd);
}
} catch (ErrnoException ex) {
Log.e(TAG, "Error reopening stdio", ex);
}
}

if (parsedArgs.niceName != null) {
// 设置进程名
Process.setArgV0(parsedArgs.niceName);
}

if (parsedArgs.invokeWith != null) {
// 用于检测进程内存泄露或溢出时场景而设计
WrapperInit.execApplication(parsedArgs.invokeWith,
parsedArgs.niceName, parsedArgs.targetSdkVersion,
VMRuntime.getCurrentInstructionSet(),
pipeFd, parsedArgs.remainingArgs);

// Should not get here.
throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
} else {
if (!isZygote) {
// 执行目标类的 main() 方法
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,
null /* classLoader */);
} else {
return ZygoteInit.childZygoteInit(parsedArgs.targetSdkVersion,
parsedArgs.remainingArgs, null /* classLoader */);
}
}
}

3.2 zygoteInit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
if (RuntimeInit.DEBUG) {
Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
}

Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
RuntimeInit.redirectLogStreams(); // 重定向 log 输出

RuntimeInit.commonInit(); // 通用的一些初始化
ZygoteInit.nativeZygoteInit(); // zygote 初始化
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader); // 应用初始化
}

我们分别看下这三个方法:

3.2.1 redirectLogStreams

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
// frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

protected static final void commonInit() {
LoggingHandler loggingHandler = new LoggingHandler();
Thread.setUncaughtExceptionPreHandler(loggingHandler);
// 设置默认的未捕捉异常处理方法
Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler(loggingHandler));

// 设置时区,中国时区为 "Asia/Shanghai"
TimezoneGetter.setInstance(new TimezoneGetter() {
@Override
public String getId() {
return SystemProperties.get("persist.sys.timezone");
}
});
TimeZone.setDefault(null);

//重置 log 配置
LogManager.getLogManager().reset();
new AndroidConfig();

// 设置默认的 HTTP User-agent 格式,用于 HttpURLConnection
String userAgent = getDefaultUserAgent();
System.setProperty("http.agent", userAgent);

// 设置 socket 的 tag,用于网络流量统计
NetworkManagementSocketTagger.install();

String trace = SystemProperties.get("ro.kernel.android.tracing");
if (trace.equals("1")) {
Slog.i(TAG, "NOTE: emulator trace profiling enabled");
Debug.enableEmulatorTraceOutput();
}

initialized = true;
}

3.2.2 nativeZygoteInit

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
// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

// nativeZygoteInit() 所对应的 jni 方法在 AndroidRuntime.cpp 中定义
private static final native void nativeZygoteInit();

// frameworks/base/core/jni/AndroidRuntime.cpp

static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
gCurRuntime->onZygoteInit(); // 此处的 gCurRuntime 为 AppRuntime
}

// frameworks/base/cmds/app_process/app_main.cpp

class AppRuntime : public AndroidRuntime
{
public:
... ...
virtual void onZygoteInit()
{
sp<ProcessState> proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
proc->startThreadPool(); // 启动新 binder 线程
}
... ...
}

3.2.3 applicationInit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {

// true 代表应用程序退出时不调用 AppRuntime.onExit(),否则会在退出前调用
nativeSetExitWithoutCleanup(true);

// 设置虚拟机的内存利用率参数值为 0.75
VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);

// 解析参数
final Arguments args = new Arguments(argv);

Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

// 此处 args.startClass 为 "android.app.ActivityThread"
return findStaticMain(args.startClass, args.startArgs, classLoader);
}

3.3 findStaticMain

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
// frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
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 {
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);
}

// 通过抛出异常,回到 ZygoteInit.main(),这样做好处是能清空栈帧,提高栈帧利用率
// m: main() 方法
// argv: ActivityThread
// 调用 MethodAndArgsCaller 的 run() 方法
return new MethodAndArgsCaller(m, argv);
}

3.4 MethodAndArgsCaller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

static class MethodAndArgsCaller implements Runnable {

public void run() {
try {
// 根据传递过来的参数,此处反射调用 ActivityThread.main() 方法
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
Throwable cause = ex.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
}
throw new RuntimeException(ex);
}
}

}

3.5 ActivityThread.main

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// frameworks/base/core/java/android/app/ActivityThread.java

public static void main(String[] args) {
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
... ...
Looper.prepareMainLooper(); // 创建主线程 looper
... ...
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq); // attach 到系统进程
... ...
Looper.loop(); // 主线程进入循环状态

throw new RuntimeException("Main thread loop unexpectedly exited");
}