Zygote启动流程(AndroidV)

一:背景

众所周知,Android应用及system_server基本都是由zygote fork出来的,那么zygote是如何启动的、又是如何接收fork进程的请求,接下来一步步揭秘。

二:启动流程

init进程是Android系统启动时,启动的第一个进程,其他所有进程基本都是由init进程来启动,其中也包括zygote,下面看下zygote的启动。

2.1 init进程启动zygote

init.rc里,在late-init阶段会触发zygote-start,zygote-start会启动zygote服务。在zygote服务中会启动app_process64(即zygote)并传入必要参数。

复制代码
//system/core/rootdir/init.rc
on late-init
    ...
    # Now we can start zygote.
    trigger zygote-start
    ...

//system/core/rootdir/init.rc
on zygote-start
    ...
    # 启动zygote服务
    start zygote
    start zygote_secondary

//system/core/rootdir/init.zygote64.rc
#启动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
    ...

2.2 zygote初始化

2.2.1 AndroidRuntime.start

  • 启动java虚拟机,根据"dalvik.vm.xxx"属性值进行初始化

  • 注册jni函数

  • 调用ZygoteInit的main函数

    //frameworks/base/cmds/app_main.cpp
    int main(int argc, char* const argv[])
    {
    ...
    bool zygote = false;
    bool startSystemServer = false;
    bool application = false;
    String8 niceName;
    String8 className;

    复制代码
      ++i;  // Skip unused "parent dir" argument.
      //获取启动参数并根据参数初始化zygote、startSystemServer等值
      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 = (arg + 12);
          } else if (strncmp(arg, "--", 2) != 0) {
              className = arg;
              break;
          } else {
              --i;
              break;
          }
      }
      ...
      if (zygote) {
          runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
      ...

    }

    //frameworks/base/core/jni/AndroidRuntime.cpp
    void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
    {
    ...
    bool primary_zygote = false;
    for (size_t i = 0; i < options.size(); ++i) {
    if (options[i] == startSystemServer) {
    primary_zygote = true;
    /* track our progress through the boot sequence /
    const int LOG_BOOT_PROGRESS_START = 3000;
    LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
    addBootEvent("boot_progress_start");
    }
    }
    ...
    //启动java虚拟机,根据"dalvik.vm.xxx"属性值进行初始化
    if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
    return;
    }
    ...
    //注册jni函数
    if (startReg(env) < 0) {
    ALOGE("Unable to register all android natives\n");
    return;
    }
    ...
    //将className中的.替换为/ ,转换之后slashClassName的值为"com/android/internal/os/ZygoteInit"
    char
    slashClassName = toSlashClassName(className != NULL ? className : "");
    jclass startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
    ...
    } else {
    //获取main函数
    jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
    "([Ljava/lang/String;)V");
    if (startMeth == NULL) {
    ...
    } else {
    //调用ZygoteInit的main函数
    env->CallStaticVoidMethod(startClass, startMeth, strArray);
    }
    }
    ...
    }

2.2.2 ZygoteInit.main

  • 在fork前做一些初始化工作,主要是enable DDMS

  • 提前加载框架通用类和系统资源

  • fork进程之前进行一次gc

  • 初始化seLinux

  • 初始化storage

  • 创建zygote的服务端对象

    //frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
    public static void main(String[] argv) {
    ZygoteServer zygoteServer = null;
    ...

    复制代码
          //zygote运行在单独的进程组中
          try {
              Os.setpgid(0, 0);
          }
          ...
    
          Runnable caller;
          try {
              ...
              bootTimingsTraceLog.traceBegin("ZygoteInit");
              //做fork前的一些初始化工作,主要是enable DDMS
              RuntimeInit.preForkInit();
    
              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]);
                  }
              }
    
              final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME);
              ...
              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
              }
    
              bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
              //fork进程之前进行一次gc
              gcAndFinalize();
              bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC
    
              bootTimingsTraceLog.traceEnd(); // ZygoteInit
    
              ...
              //native初始化
              Zygote.initNativeState(isPrimaryZygote);
              ...
              //创建zygote的服务端对象
              zygoteServer = new ZygoteServer(isPrimaryZygote);
    
    
              if (startSystemServer) {
                  //fork system_server进程
                  Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
                  if (r != null) {
                      r.run();
                      return;
                  }
              }
    
              ...
              caller = zygoteServer.runSelectLoop(abiList);
          }
          ...
    
          //在单独的线程中接收来自应用的zygote请求
          if (caller != null) {
              caller.run();
          }
      }

    //frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
    static void preload(TimingsTraceLog bootTimingsTraceLog) {
    ...
    //加载/system/etc/preloaded-classes定义的所有的类
    preloadClasses();
    ...
    //加载frameworks/base/core/res/res/values/arrays.xml中preloaded_drawables和preloaded_color_state_lists定义的所有资源
    Resources.preloadResources();
    ...
    //加载graphic的hal
    nativePreloadAppProcessHALs();
    ...
    //加载graphic
    maybePreloadGraphicsDriver();
    ...
    //加载android、jnigraphics、compiler_rt这三个共享库
    preloadSharedLibraries();
    //加载字体资源
    preloadTextResources();
    ...
    }

    //frameworks/base/core/java/com/android/internal/os/Zygote.java
    static void initNativeState(boolean isPrimary) {
    nativeInitNativeState(isPrimary);
    }

    //frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
    static void com_android_internal_os_Zygote_nativeInitNativeState(JNIEnv* env, jclass,
    jboolean is_primary) {
    //从环境中获取init创建的文件描述符。
    gZygoteSocketFD =
    android_get_control_socket(is_primary ? "zygote" : "zygote_secondary");
    ...
    //创建用于向system_server发送未经请求的消息的socket,在app申请zygote fork进程时被调用,fork完成后关闭
    initUnsolSocketToSystemServer();
    ...
    //初始化seLinux
    gIsSecurityEnforced = security_getenforce();
    selinux_android_seapp_context_init();

    复制代码
    //初始化storage
    UnmountStorageOnInit(env);
    
    //设置高优先级
    if (!SetTaskProfiles(0, {})) {
      zygote::ZygoteFailure(env, "zygote", nullptr, "Zygote SetTaskProfiles failed");
    }

    }

2.2.3 ZygoteInit.forkSystemServer

  • 设置启动system_server的参数,例如uid、gid、进程名称等

  • 调用Linux的fork函数来实现fork system_server进程

    //frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
    private static Runnable forkSystemServer(String abiList, String socketName,
    ZygoteServer zygoteServer) {
    ...
    //设置启动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,3005,3006,3007,3009,3010,3011,3012",
    "--capabilities=" + capabilities + "," + capabilities,
    "--nice-name=system_server",
    "--runtime-args",
    "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
    "com.android.server.SystemServer",
    };
    ...
    try {
    ...
    //fork system_server
    pid = Zygote.forkSystemServer(...);
    }
    ...

    复制代码
          //子进程
          if (pid == 0) {
              ...
              zygoteServer.closeServerSocket();
              return handleSystemServerProcess(parsedArgs);
          }
          ...
      }

    //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);
    
          //设置线程优先级为NORM_PRIORITY
          Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
          //ZygoteHooks.postForkCommon是Zygote进程中的一个钩子函数,它在Zygote进程fork出子进程后被调用。这个钩子函数的作用是在子进程中执行一些初始化操作,例如创建Binder线程池和消息循环等。
          ZygoteHooks.postForkCommon();
          return pid;
      }

    //frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
    static jint com_android_internal_os_Zygote_nativeForkSystemServer(...) {
    ...
    pid_t pid = zygote::ForkCommon(env, true,
    fds_to_close,
    fds_to_ignore,
    true);
    ...
    return pid;
    }

    //frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
    pid_t zygote::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,
    bool purge) {
    ATRACE_CALL();
    if (is_priority_fork) {//设置最大优先级
    setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MAX);
    }

    复制代码
    //设置信号处理程序
    SetSignalHandlers();
    ...
    //阻断信号
    BlockSignal(SIGCHLD, fail_fn);
    
    ...
    //真正fork进程的地方,在父进程中,fork()返回新创建子进程的PID,而在子进程中,fork()返回0。
    pid_t pid = fork();
    
    ...
    //解除阻断信号
    UnblockSignal(SIGCHLD, fail_fn);
    
    if (is_priority_fork && pid != 0) {//设置优先级为PROCESS_PRIORITY_DEFAULT
      setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_DEFAULT);
    }
    
    return pid;

    }

2.2.4 RuntimeInit.applicationInit

  • 获取SystemServer.java类对应的ClassLoader
  • 初始化时区、User-Agent等
  • 开启线程池
  • 调用SystemServer的main函数,开始启动系统服务等

这个时候system_server进程就启动了,开始启动系统服务等

复制代码
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
    private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
        ...
        if (parsedArgs.mInvokeWith != null) {
            ...
        } else {
            //获取SystemServer.java类对应的ClassLoader
            ClassLoader cl = getOrCreateSystemServerClassLoader();
            ...
            return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                    parsedArgs.mDisabledCompatChanges,
                    parsedArgs.mRemainingArgs, cl);
        }
    }

//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
    public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
            String[] argv, ClassLoader classLoader) {
        ...
        //初始化时区、User-Agent等
        RuntimeInit.commonInit();
        //开启线程池
        ZygoteInit.nativeZygoteInit();
        return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
                classLoader);
    }

//frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
    protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
            String[] argv, ClassLoader classLoader) {
        ...
        return findStaticMain(args.startClass, args.startArgs, classLoader);
    }

//frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
    protected static Runnable findStaticMain(String className, String[] argv,
            ClassLoader classLoader) {
        Class<?> cl;

        try {
            //获取SystemServer类
            cl = Class.forName(className, true, classLoader);
        }
        ...

        Method m;
        try {
            //获取main函数
            m = cl.getMethod("main", new Class[] { String[].class });
        }
        ...
        //调用SystemServer的main函数,开始启动系统服务等
        return new MethodAndArgsCaller(m, argv);
    }

2.2.5 ZygoteServer.runSelectLoop

在线程里启动一个死循环,接收请求fork的socket请求

复制代码
//frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
    Runnable runSelectLoop(String abiList) {
        ...
        while (true) {
            ...
            if (pollReturnValue == 0) {
                ...
            } else {
                ...
                while (--pollIndex >= 0) {
                    if (pollIndex == 0) {
                        ...
                    } else if (pollIndex < usapPoolEventFDIndex) {
                        try {
                            //获取socket连接
                            ZygoteConnection connection = peers.get(pollIndex);
                            boolean multipleForksOK = !isUsapPoolEnabled()
                                    && ZygoteHooks.isIndefiniteThreadSuspensionSafe();
                            //处理来自应用请求fork的socket请求
                            final Runnable command =
                                    connection.processCommand(this, multipleForksOK);
                        }
                        ...
                    }
                }
                ...
            }
            ...
        }
    }

三:小结

3.1 zygote进程是否只有一个?

答:不是。

zygote进程一般都会有zygote和zygote64两个,分别用来fork32位和64位的应用,这两个进程都是在init.rc中启动的。

如果系统中有webview类应用,那么还会存在webview_zygote这个进程,用来fork webview类应用。webview_zygote进程的启动是在ProcessList的startProcess函数中判断是否是webview类型应用,如果是则会调用Process的startWebView函数,接着会判断webview_zygote进程是否存在,如果不存在则调用zygote fork出来。

3.2 是否每次应用冷启动时都要调用zygote的fork函数?

答:不是。

Android系统有usap机制,会在Android系统启动时,开启一个进程池。如果usap功能打开,当有fork请求到来时,会先从进程池中取出一个进程返回,节约启动时间。

相关推荐
阿巴斯甜9 小时前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker9 小时前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq952710 小时前
Andorid Google 登录接入文档
android
黄林晴11 小时前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab1 天前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿1 天前
Android MediaPlayer 笔记
android
Jony_1 天前
Android 启动优化方案
android
阿巴斯甜1 天前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android
张小潇1 天前
AOSP15 Input专题InputReader源码分析
android
_小马快跑_1 天前
Kotlin | 协程调度器选择:何时用CoroutineScope配置,何时用launch指定?
android