Zygote进程

Zygote进程

概述

Zygote 是所有应用的鼻祖,SystemServer以及其他应用进程均是由 Zygote fork而来

  • Zygote进程 由app_process启动 Zygote是C/S模型,Zygote进程作为服务端,其他进程作为客户端向其发送请求,Zygote接收到请求后进行fork一个新的进程
  • Zygote在启动时创建一个java虚拟机,通过fork创建的进程可以在内部获取一个java虚拟机的拷贝

Zygote 启动

Zygote进程由init进程启动,具体流程:
app_main.cpp -> AndroidRuntime.cpp(在此通过调用StartVM 方法创建虚拟机)-> 通过JNI调用ZygoteInit.main方法,进入Java层
在main方法中创建了ZygoteServer,作为服务端,接收来自客户端的请求。
接下来main中做了两件事情:

  • 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) {
         r.run();
         return;
     }
 }

进入forkSystemServer可以看到最后调用的是Zygote.forkSystemServer,用以启动SystemServer进程,然后调用native方法进行进程的fork,返回的是PID

int pid;

        try {
            parsedArgs = new ZygoteArguments(args);
            Zygote.applyDebuggerSystemProperty(parsedArgs);
            Zygote.applyInvokeWithSystemProperty(parsedArgs);

            boolean profileSystemServer = SystemProperties.getBoolean(
                    "dalvik.vm.profilesystemserver", false);
            if (profileSystemServer) {
                parsedArgs.mRuntimeFlags |= Zygote.PROFILE_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);
        }

        /* For child process */
    if (pid == 0) {
        if (hasSecondZygote(abiList)) {
            waitForSecondaryZygote(socketName);
        }

        zygoteServer.closeServerSocket();
        return handleSystemServerProcess(parsedArgs);
    }

fork成功后接下来调用handleSystemServerProces方法

private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
    // set umask to 0077 so new files and directories will default to owner-only permissions.
    Os.umask(S_IRWXG | S_IRWXO);


    if (parsedArgs.mNiceName != null) {
        Process.setArgV0(parsedArgs.mNiceName);
    }

    final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
    if (systemServerClasspath != null) {
        if (performSystemServerDexOpt(systemServerClasspath)) {
            // Throw away the cached classloader. If we compiled here, the classloader would
            // not have had AoT-ed artifacts.
            // Note: This only works in a very special environment where selinux enforcement is
            // disabled, e.g., Mac builds.
            sCachedSystemServerClassLoader = null;
        }
        // Capturing profiles is only supported for debug or eng builds since selinux normally
        // prevents it.
        boolean profileSystemServer = SystemProperties.getBoolean(
                "dalvik.vm.profilesystemserver", false);
        if (profileSystemServer && (Build.IS_USERDEBUG || Build.IS_ENG)) {
            try {
                prepareSystemServerProfile(systemServerClasspath);
            } catch (Exception e) {
                Log.wtf(TAG, "Failed to set up system server profile", e);
            }
        }
    }

    if (parsedArgs.mInvokeWith != null) {
        String[] args = parsedArgs.mRemainingArgs;
        // If we have a non-null system server class path, we'll have to duplicate the
        // existing arguments and append the classpath to it. ART will handle the classpath
        // correctly when we exec a new process.
        if (systemServerClasspath != null) {
            String[] amendedArgs = new String[args.length + 2];
            amendedArgs[0] = "-cp";
            amendedArgs[1] = systemServerClasspath;
            System.arraycopy(args, 0, amendedArgs, 2, args.length);
            args = amendedArgs;
        }

        WrapperInit.execApplication(parsedArgs.mInvokeWith,
                parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
                VMRuntime.getCurrentInstructionSet(), null, args);

        throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
    } else {
        createSystemServerClassLoader();
        ClassLoader cl = sCachedSystemServerClassLoader;
        if (cl != null) {
            Thread.currentThread().setContextClassLoader(cl);
        }

        /*
         * Pass the remaining arguments to SystemServer.
         */
        return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                parsedArgs.mRemainingArgs, cl);
    }

    /* should never reach here */
}

在前面方法中的args没有invokeWith因此不会走if而是直接走else。
继续执行Zygote.zygoteInit()方法,然后调用RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader),以及findStaticMain(args.startClass, args.startArgs, classLoader)

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);
    }

    /*
     * This throw gets caught in ZygoteInit.main(), which responds
     * by invoking the exception's run() method. This arrangement
     * clears up all the stack frames that were required in setting
     * up the process.
     */
    return new MethodAndArgsCaller(m, argv);
}

在findStaticMain方法中实际是利用反射调用SystemServer.java中的main方法。

  • zygoteServer.runSelectLoop(abiList)
    ZygoteConnection connection = peers.get(pollIndex);
    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;
    } 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 processOneCommand. This
        // shows up as a regular POLLIN event in our regular processing loop.
        if (connection.isClosedByPeer()) {
            connection.closeSocket();
            peers.remove(pollIndex);
            socketFDs.remove(pollIndex);
        }
    }

在上面代码中处理其他进程(比如AMS)发送过来的连接请求,继续看processCommand方法

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.mTargetSdkVersion);

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

         zygoteServer.closeServerSocket();
         IoUtils.closeQuietly(serverPipeFd);
         serverPipeFd = null;

         return handleChildProc(parsedArgs, descriptors, 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, descriptors, serverPipeFd);
         return null;
     }
 } finally {
     IoUtils.closeQuietly(childPipeFd);
     IoUtils.closeQuietly(serverPipeFd);
 }

接收到其他进程发过来的请求后,Zygote进程会fork出一个新的进程,然后调用 ZygoteConnection.handleChildProc

private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors,
            FileDescriptor pipeFd, boolean isZygote) {
        /**
         * By the time we get here, the native code has closed the two actual Zygote
         * socket connections, and substituted /dev/null in their place.  The LocalSocket
         * objects still need to be closed properly.
         */

  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.mNiceName != null) {
      Process.setArgV0(parsedArgs.mNiceName);
  }

  // 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) {
          return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                  parsedArgs.mRemainingArgs, null /* classLoader */);
      } else {
          return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
                  parsedArgs.mRemainingArgs, null /* classLoader */);
      }
  }
}

此时fork出来的进程不是zygote因此,继续执行childZygoteInit

    static final Runnable childZygoteInit(
            int targetSdkVersion, String[] argv, ClassLoader classLoader) {
        RuntimeInit.Arguments args = new RuntimeInit.Arguments(argv);
        return RuntimeInit.findStaticMain(args.startClass, args.startArgs, classLoader);
    }

跟forkSystemServer一样,最后会走到RuntimeInit.findStaticMain方法,通过反射调用传递过去的class的main方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值