Zygote 进程由init进程启动,是systemserver 进程和APP 进程的父进程
先看一下rc文件,以init.zygote32.rc为例
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
priority -20
user root
group root readproc reserved_disk
socket zygote stream 660 root system
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
writepid /dev/cpuset/foreground/tasks
其实就是执行 /system/bin/app_process ,传入“-Xzygote /system/bin --zygote --start-system-server” 参数。 /system/bin/app_process是由frameworks\base\cmds\app_process\app_main.cpp 编译得到的,所以执行 /system/bin/app_process 就是执行app_main.cpp 的main函数
//frameworks\base\cmds\app_process\app_main.cpp
int main(int argc, char* const argv[])
{
//......
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
// Process command line arguments
// ignore argv[0]
//忽略-Xzygote参数
argc--;
argv++;
//......
//遍历参数
while (i < argc) {
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) {
zygote = true;
niceName = ZYGOTE_NICE_NAME;
} else if (strcmp(arg, "--start-system-server") == 0) {
startSystemServer = true;
} else if (strcmp(arg, "--application") == 0) {
application = true;
} else if (strncmp(arg, "--nice-name=", 12) == 0) {
niceName.setTo(arg + 12);
} else if (strncmp(arg, "--", 2) != 0) {
className.setTo(arg);
break;
} else {
--i;
break;
}
}
//经过上面的遍历,zygote 为true,startSystemServer 为true
Vector<String8> args;
//......
// We're in zygote mode.
maybeCreateDalvikCache();
if (startSystemServer) {
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);
args.add(abiFlag);
// In zygote mode, pass all remaining arguments to the zygote
// main() method.
for (; i < argc; ++i) {
args.add(String8(argv[i]));
}
}
//zygote为true
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
} else {
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
app_usage();
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
}
主要就是解析参数,根据传入的参数,构造args,单后调用runtime的start函数。 runtime是AppRuntime 对象,继承 AndroidRuntime,调用runtime的start函数,即调动到其父类AndroidRuntime类中start函数
//frameworks\base\core\jni\AndroidRuntime.cpp
//注意这里传入的className为com.android.internal.os.ZygoteInit
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
//......
/* 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.
*/
if (startReg(env) < 0) { //注册JNI函数,后续要添加自己的JNI文件的话,可以参考这个函数里面的实现
ALOGE("Unable to register all android natives\n");
return;
}
//......
char* slashClassName = toSlashClassName(className != NULL ? className : "");
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} else {
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V"); //找到ZygoteInit的main方法
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
/* keep going */
} else {
env->CallStaticVoidMethod(startClass, startMeth, strArray);//执行main方法
//......
在start函数中,主要做了以下工作:
- 启动虚拟机
- 注册JNI函数
- 执行ZygoteInit的main方法
//frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
@UnsupportedAppUsage
public static void main(String argv[]) {
ZygoteServer zygoteServer = null;
/*1,设置参数*/
boolean startSystemServer = false;
String zygoteSocketName = "zygote";
String abiList = null;
boolean enableLazyPreload = false;
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
} else if ("--enable-lazy-preload".equals(argv[i])) {
enableLazyPreload = true;
} else if (argv[i].startsWith(ABI_LIST_ARG)) {
abiList = argv[i].substring(ABI_LIST_ARG.length());
} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());
} else {
throw new RuntimeException("Unknown command line argument: " + argv[i]);
}
}
//......
/*2,预加载*/
if (!enableLazyPreload) {
bootTimingsTraceLog.traceBegin("ZygotePreload");
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
preload(bootTimingsTraceLog);
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
bootTimingsTraceLog.traceEnd(); // ZygotePreload
}
/*3,fork systemserver进程*/
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
// {@code r == null} in the parent (zygote) process, and {@code r != null} in the
// child (system_server) process.
if (r != null) {//4,启动systemserver进程
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.
caller = zygoteServer.runSelectLoop(abiList);//5,等待APP请求创建进程
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with 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();//创建成功,启动APP进程
}
在main函数中主要做了以下工作:
- 预加载资源
- fork systemserver进程并启动
- 阻塞等待APP创建进程的请求,有请求的话,fork出APP进程
接下来看看Zygote是怎么创建出systemserver进程以及处理APP请求的,即分析forkSystemServer和runSelectLoop方法。systemserver进程的启动在分析systemserver的时候再分析。
forkSystemServer
//frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
//......
/* Hardcoded command line to start the system server */
/*注意最后一个参数是com.android.server.SystemServer*/
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 = null;
int pid;
try {
//根据参数构造ZygoteArguments
parsedArgs = new ZygoteArguments(args);
//......
/* 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);
}
/* For child process */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
//这里返回一个Runnable ,然后在ZygoteInit的main函数中调用此Runnable 的run方法,启动systemserver
return handleSystemServerProcess(parsedArgs);
}
return null;
}
先构造参数,然后调用Zygote的forkSystemServer方法。fork成功之后,如果是子线程,则返回一个Runnable
//frameworks\base\core\java\com\android\internal\os\Zygote.java
static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
ZygoteHooks.preFork();
int pid = nativeForkSystemServer(
uid, gid, gids, runtimeFlags, rlimits,
permittedCapabilities, effectiveCapabilities);
// Set the Java Language thread priority to the default value for new apps.
Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
ZygoteHooks.postForkCommon();
return pid;
}
继续调用nativeForkSystemServer方法,对应JNI的com_android_internal_os_Zygote_nativeForkSystemServer方法
//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 nice_name,
jintArray managed_fds_to_close, jintArray managed_fds_to_ignore, jboolean is_child_zygote,
jstring instruction_set, jstring app_data_dir, jboolean is_top_app,
jobjectArray pkg_data_info_list, jobjectArray whitelisted_data_info_list,
jboolean mount_data_dirs, jboolean mount_storage_dirs) {
//......
pid_t pid = ForkCommon(env, false, fds_to_close, fds_to_ignore, true);
if (pid == 0) {
SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
capabilities, capabilities,
mount_external, se_info, nice_name, false,
is_child_zygote == JNI_TRUE, instruction_set, app_data_dir,
is_top_app == JNI_TRUE, pkg_data_info_list,
whitelisted_data_info_list,
mount_data_dirs == JNI_TRUE,
mount_storage_dirs == JNI_TRUE);
}
return pid;
}
static pid_t ForkCommon(JNIEnv* env, bool is_system_server,
const std::vector<int>& fds_to_close,
const std::vector<int>& fds_to_ignore,
bool is_priority_fork) {
//......
pid_t pid = fork();
//......
}
可以看出,通过调用fork函数,fork出systemserver子进程
runSelectLoop
runSelectLoop对于Zygote进程来说,是一个死循环,利用poll机制,没事件的时候就阻塞等待
Runnable runSelectLoop(String abiList) {
ArrayList<FileDescriptor> socketFDs = new ArrayList<>();
ArrayList<ZygoteConnection> peers = new ArrayList<>();
socketFDs.add(mZygoteSocket.getFileDescriptor());
peers.add(null);
mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP;
while (true) {
//......
try {
pollReturnValue = Os.poll(pollFDs, pollTimeoutMs);
} catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex);
}
//.......
}
有事件请求,调用processOneCommand,如果是创建子进程的请求,就创建子进程,并在子进程中返回一个Runnable,供ZygoteInit去启动子进程(注意:父进程即Zygote还是在运行,并不会返回退出)
//......
final Runnable command = connection.processOneCommand(this);
// 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 processOneCommand hasn't called "exec".
if (command == null) {
throw new IllegalStateException("command == null");
}
return command;
//......
在processOneCommand方法中调用forkAndSpecialize ,创建子进程
Runnable processOneCommand(ZygoteServer zygoteServer) {
//......
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.mWhitelistedDataInfoList,
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);
//......
}
后面也是和fork systemserver进程一样,进入JNI,通过调用fork,创建子进程。所以zogyte的runSelectLoop方法,就是监听客户端事件,如果客户端请求创建进程,则fork出子进程。
总结
Zygote进程启动过程中,主要做了以下事情
- 启动虚拟机
- 注册JNI函数
- 预加载资源
- fork 出 systemserver进程并去启动它
- 等待客户端的请求,如果客户端请求创建进程,则fork进程并去启动它
另外,Android 11 Zygote 可支持使用线程池创建子进程,来优化应用的启动速度。参考Zygote pre-fork线程池源码分析
标签:11,--,......,system,Zygote,zygote,进程,Android,parsedArgs From: https://blog.csdn.net/littleyards/article/details/136651283