Android 9.0 Zygote 啓動流程

本篇文章主要介紹 Android Zygote 啓動分析 知識點,經過閱讀本篇文章,您將收穫如下內容:java

1、 Android 系統基本服務
2、虛擬機建立和第一個Java 程序引導
3、Dalvik 虛擬機基本配置
4、Zygote 啓動流程
5、Zygote 啓動分析
6、Zygote 建立system_server主要方法
7、Zygote 建立System_server 分析
8、Zygote 建立應用
9、Zygote 建立應用流程
10、Zygote 預加載資源
11、Zygote 預加載的目的
12、優化Zygote 啓動方法: 線程池
十3、fork SystemServer

Zygote 服務時經過 init.rc進程啓動的,Zygoteclassnamemain .
init.rc 文件配置代碼以下:android

... ... 
on nonencrypted
    class_start main
    class_start late_start

on property:sys.init_log_level=*
    loglevel ${sys.init_log_level}

... ...

詳細能夠參考 init.rc啓動分析。
Android 9.0 init 啓動流程程序員

Zygote 進程的main 函數

app_main.cpp Zygote進程的main函數,frameworks\base\cmds\app_process\app_main.cpp微信

1、 Android 系統基本服務

Android 系統包含netdservicemanagersurfaceflingerzygotemediainstalldbootanimation 等基本服務,具體做用請看下圖。多線程

Android 系統基本服務

2、虛擬機建立和第一個Java 程序引導

爲了讓APK在不一樣的虛擬機均可以運行,Google 採起了適配器模式,在讓虛擬機運行以前先執行 dexopt ,即將dex 文件優化成odex 文件,可讓虛擬機更加優化的執行。app

ART 虛擬機中,dexoptdex文件優化成二進制格式的問題,從而可讓ART虛擬機執行。dexopt 會調用dex2oat 進行優化,dex2oat 的任務是將原來的dex文件進行預翻譯,從而能夠加快app運行的時間,可是因爲某些app比較複雜,因此優化的時間就比較長。
優化是以dex 文件中的Method 方法爲單位,dex2oat 在優化時候,會根據需求優化必定量的Method,即不是全部的Method 都回翻譯成oat模式。socket

虛擬機建立和第一個Java 程序引導

3、Dalvik 虛擬機基本配置

Android 系統中,Dalvik 虛擬機 和ART、應用程序進程,以及運行系統的關鍵服務SystemServer 進程都是由 Zygote 進程建立孵化的。ide

Dalvik 虛擬機基本配置以下:函數

Dalvik 虛擬機基本配置

4、Zygote 啓動流程

Zygote 是由 init.rc 腳本啓動,在init 腳本中,咱們能夠看到會導入import /init.${ro.zygote}.rc 腳本優化

# Copyright (C) 2012 The Android Open Source Project
#
# IMPORTANT: Do not create world writable files or directories.
# This is a common source of Android security bugs.
#

import /init.environ.rc
import /init.usb.rc
import /init.${ro.hardware}.rc
import /vendor/etc/init/hw/init.${ro.hardware}.rc
import /init.usb.configfs.rc
... ...
import /init.${ro.zygote}.rc

... ...

system/core/rootdir目錄下,會根據ro.zygote屬性值不一樣,啓動不一樣的腳本,主要包含如下四個zygote 腳本。

  • 1.init.zygote32.rc 支持32爲系統
  • 2.init.zygote32_64.rc
  • 3.init.zygote64.rc
  • 4.init.zygote64_32.rc

init.zygte.rc腳本

Zygote 啓動流程

5、Zygote 啓動分析

Zygote 啓動分析

6、Zygote 建立system_server主要方法

Zygote 建立system_server主要方法

7、Zygote 建立System_server 分析

Zygote 建立System_server

8、Zygote 建立應用

Zygote 建立應用

9、Zygote 建立應用流程

Zygote 建立應用流程

10、Zygote 預加載資源

Zygote 預加載資源

preloadClasses()

preloadResources()

11、Zygote 預加載的目的

Zygote 預加載的目的

12、優化Zygote 啓動方法: 線程池

Zygote 啓動優化前提:

  • 1:加載類和資源是可重入操做,因此在並行模式下,不存在互斥的場景
  • 2:Android提供了ExecutorsExecutorService多線程類,所以可使用多線程來加載類和資源。
  • 3:硬件平臺最好是多核,不然加速也不明顯;

線程池 優化Zygote 啓動

Zygote 啓動優化實質:

使咱們的進程最大限度的搶佔CPU

十3、fork SystemServer

通過一系列初始化後,在ZygoteInit類中 forkSystemServer,爲啓動SystemServer 作準備。ZygoteInit.java代碼路徑以下:alps\frameworks\base\core\java\com\android\internal\os\ZygoteInit.java

/**
     * 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,
            OsConstants.CAP_BLOCK_SUSPEND
        );
        /* Containers run without some capabilities, so drop any caps that are not available. */
        StructCapUserHeader header = new StructCapUserHeader(
                OsConstants._LINUX_CAPABILITY_VERSION_3, 0);
        StructCapUserData[] data;
        try {
            data = Os.capget(header);
        } catch (ErrnoException ex) {
            throw new RuntimeException("Failed to capget()", ex);
        }
        capabilities &= ((long) data[0].effective) | (((long) data[1].effective) << 32);

        /* Hardcoded command line to start the system server */
        String args[] = {
            "--setuid=1000",
            "--setgid=1000",
            /// M: [Wi-Fi Hotspot Manager] system_server add dhcp (1014) group to access
            /// "/data/misc/dhcp/dnsmasq.leases"
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1014,1018,1021,1023," +
                        "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010",
            "--capabilities=" + capabilities + "," + capabilities,
            "--nice-name=system_server",
            "--runtime-args",
            "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
            "com.android.server.SystemServer",
        };
        ZygoteConnection.Arguments parsedArgs = null;

        int pid;

        try {
            parsedArgs = new ZygoteConnection.Arguments(args);
            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

            boolean profileSystemServer = SystemProperties.getBoolean(
                    "dalvik.vm.profilesystemserver", false);
            if (profileSystemServer) {
                parsedArgs.runtimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
            }

            /* Request to fork the system server process */
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.runtimeFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

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

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

        return null;
    }

至此,本篇已結束,若有不對的地方,歡迎您的建議與指正。同時期待您的關注,感謝您的閱讀,謝謝!

微信關注公衆號:  程序員Android,領福利

相關文章
相關標籤/搜索