Android 8.1 源码_启动篇(二) -- 深入研究 zygote (7)

上面是ZygoteInit的main函数的主干部分,除了安全相关的内容外,最主要的工作就是注册server socket、预加载、启动system server及进入无限循环处理请求消息。

接下来我们分四部分分别讨论!

创建server socket

Android O将server socket相关的工作抽象到ZygoteServer.java中了。我们来看看其中的registerZygoteSocket函数:

/** * Registers a server socket for zygote command connections * * @throws RuntimeException when open fails */ void registerServerSocket(String socketName) { if (mServerSocket == null) { int fileDesc; // ANDROID_SOCKET_PREFIX为"ANDROID_SOCKET_" // 此处的socket name,就是zygote final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName; try { // 还记得么?在init.zygote.rc被加载时,指定了名为zygote的socket // 在进程被创建时,就会创建对应的文件描述符,并加入到环境变量中 // 因此,此时可以取出对应的环境变量 String env = System.getenv(fullSocketName); fileDesc = Integer.parseInt(env); } catch (RuntimeException ex) { throw new RuntimeException(fullSocketName + " unset or invalid", ex); } try { FileDescriptor fd = new FileDescriptor(); fd.setInt$(fileDesc); // 获取zygote socket的文件描述符 mServerSocket = new LocalServerSocket(fd); // 将socket包装成一个server socket } catch (IOException ex) { throw new RuntimeException( "Error binding to local socket '" + fileDesc + "'", ex); } } }

我们跟踪LocalServerSocket():

public LocalServerSocket(String name) throws IOException { impl = new LocalSocketImpl(); impl.create(LocalSocket.SOCKET_STREAM); // 创建SOCKET_STREAM类型的AF_UNIX socket localAddress = new LocalSocketAddress(name); impl.bind(localAddress); // 绑定到指定地址 impl.listen(LISTEN_BACKLOG); // 开始监听 } 预加载

我们看看预加载的内容:

static void preload(TimingsTraceLog bootTimingsTraceLog) { ... ... beginIcuCachePinning(); // Pin ICU Data, 获取字符集转换资源等 ... ... preloadClasses(); // 读取文件system/etc/preloaded-classes,然后通过反射加载对应的类 // 一般由厂商来定义,有时需要加载数千个类,启动慢的原因之一 ... ... preloadResources(); // 负责加载一些常用的系统资源 ... ... nativePreloadAppProcessHALs(); ... ... preloadOpenGL(); // 图形相关 ... ... preloadSharedLibraries(); // 一些必要库 preloadTextResources(); // 语言相关的字符信息 // Ask the WebViewFactory to do any initialization that must run in the zygote process, // for memory sharing purposes. WebViewFactory.prepareWebViewInZygote(); endIcuCachePinning(); warmUpJcaProviders(); // 安全相关的 Log.d(TAG, "end preload"); sPreloadComplete = true; }

为了让系统实际运行时更加流畅,在zygote启动时候,调用preload函数进行了一些预加载操作。Android 通过zygote fork的方式创建子进程。zygote进程预加载这些类和资源,在fork子进程时,仅需要做一个复制即可。
这样可以节约子进程的启动时间。同时,根据fork的copy-on-write机制可知,有些类如果不做改变,甚至都不用复制,子进程可以和父进程共享这部分数据,从而省去不少内存的占用。

启动SystemServer进程

再来看看启动System Server的流程:

/** * Prepare the arguments and forks for the system server process. * * Returns an {@code Runnable} that provides an entrypoint into system_server code in the * child process, and {@code null} in the parent. */ 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 ); /* Containers run without this capability, so avoid setting it in that case */ if (!SystemProperties.getBoolean(PROPERTY_RUNNING_IN_CONTAINER, false)) { capabilities |= posixCapabilitiesAsBits(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,1032,3001,3002,3003,3006,3007,3009,3010", "--capabilities=" + capabilities + "," + capabilities, "--nice-name=system_server", "--runtime-args", "com.android.server.SystemServer", }; ZygoteConnection.Arguments parsedArgs = null; int pid; try { parsedArgs = new ZygoteConnection.Arguments(args); // 将上面准备的参数,按照ZygoteConnection的风格进行封装 ZygoteConnection.applyDebuggerSystemProperty(parsedArgs); ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs); /* Request to fork the system server process */ pid = Zygote.forkSystemServer( // 通过fork"分裂"出system_server parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, null, parsedArgs.permittedCapabilities, parsedArgs.effectiveCapabilities); } catch (IllegalArgumentException ex) { throw new RuntimeException(ex); } /* 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; } 处理请求信息

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zygdyw.html