Zygote 进程启动过程

Android 进阶——系统启动之核心SystemServer进程启动详解(七) 在Zygote 进程启动过程中会把Android 最核心进程SystemServer进程创建并启动。 阅读详情

Android 系统启动系列文章:

首语

在Android系统中,DVM(Dalvik虚拟机)和ART、应用程序进程以及运行系统的关键服务的SystemServer进程都是由Zygote进程创建的,也可以将其称之为孵化器,它通过fork(复制进程)的形式来创建应用程序进程和SystemServer进程。

Zygote进程是在init进程启动时创建的,起初Zygote的进程名称为"app_process",在frameworks/base/cmds/app_process/Android.bp中定义,Zygote启动后,会将其名称转换为"zygote"或"zygote64"(后面分析源码会讲到)。

Zygote启动脚本

在init.rc文件中采用了Import类型的语句来引入Zygote启动脚本。

import /system/etc/init/hw/init.${ro.zygote}.rc

init.rc不会引入一个固定的rc文件,而是根据属性ro.zygote来引入不同的文件。ro.zygote属性的取值有以下3种:

  • init.zygote32.rc
  • init.zygote64.rc
  • init.zygote64_32.rc

这些Zygote脚本都放在system/core/rootdir目录中。下面分别介绍这些Zygote启动脚本

init.zygote32.rc

表示支持纯32位程序,内容如下:

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 media.tuner
    onrestart restart netd
    onrestart restart wificond
    task_profiles ProcessCapacityHigh
    critical window=${zygote.critical_window.minute:-off} target=zygote-fatal

根据在 init进程启动过程 文章中所描述的Service类型语句的格式,可知,Zygote进程名称为zygote,执行程序为app_process,classname为main,如果audioserver、cameraserver、media等进程终止,就需要restart.

init.zygote64.rc

表示支持64位程序,这个启动脚本在 init进程启动过程 文章中已经进行解释,不在重复讲述。

init.zygote64_32.rc

表示既支持64位程序也支持32位程序,64位为主,32位为辅。现在主流都是init.zygote64_32.rc。内容如下:

service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
    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 media.tuner
    onrestart restart netd
    onrestart restart wificond
    task_profiles ProcessCapacityHigh MaxPerformance
    critical window=${zygote.critical_window.minute:-off} target=zygote-fatal

service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary --enable-lazy-preload
    class main
    priority -20
    user root
    group root readproc reserved_disk
    socket zygote_secondary stream 660 root system
    socket usap_pool_secondary stream 660 root system
    onrestart restart zygote
    task_profiles ProcessCapacityHigh MaxPerformance
    disabled

脚本中由两个service类型语句,说明会启动两个Zygote进程,一个名称位zygote,执行程序为app_process64,作为主模式。另一个名称为zygote_secondary,执行程序为app_process32,作为辅模式。

Zygote进程启动过程

在 init进程启动过程 文章中我们知道init启动Zygote主要是调用app_main.cpp的main函数中的AndroidRuntime的start函数来启动Zygote进程的,首先从app_main.cpp的main函数分析。

Zygote进程都是通过fork自身来创建子进程,这样Zygote进程以及它的子进程都可以进入main函数,因此main函数有区分当前运行在那个进程,根据参数arg是否包含"–zygote"来判断,如果包含则说明当前运行在Zygote进程,zygote = true;,包含"–start-system-server"则说明当前运行在SystemServer进程,startSystemServer = true;。运行在Zygote进程,就会调用AndroidRuntime的start函数(AppRuntime继承于AndroidRuntime,没有实现start函数,所以直接查看AndroidRuntime。

源码路径:frameworks\base\cmds\app_process\app_main.cpp

#if defined(__LP64__)
static const char ABI_LIST_PROPERTY[] = "ro.product.cpu.abilist64";
static const char ZYGOTE_NICE_NAME[] = "zygote64";
#else
static const char ABI_LIST_PROPERTY[] = "ro.product.cpu.abilist32";
static const char ZYGOTE_NICE_NAME[] = "zygote";
#endif

int main(int argc, char* const argv[])
{
	...
    while (i < argc) {
        const char* arg = argv[i++];
        if (strcmp(arg, "--zygote") == 0) {
            //如果当前运行在Zygote进程中,则将zygote设置为true
            zygote = true;
            niceName = ZYGOTE_NICE_NAME;
        } else if (strcmp(arg, "--start-system-server") == 0) {
            //如果当前运行在SystemServer进程中,则将zygote设置为true
            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;
        }
    }
	...
    if (!niceName.isEmpty()) {
        //首语提到Zygote的进程名称为"app_process",启动后会修改为niceName=ZYGOTE_NICE_NAME,ZYGOTE_NICE_NAME会根据系统为zygote64或zygote
        runtime.setArgv0(niceName.string(), true /* setProcName */);
    }
  	//运行在Zygote进程
    if (zygote) {
            runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } else if (className) {
        //application启动模式
        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.");
    }
}

startVm函数创建虚拟机,再通过startReg注册JNI方法。将className的".“替换为”/",是为了找到ZygoteInit,再调用ZygoteInit的main方法,因为ZygoteInit的main方法是java语言实现的,所以需要通过JNI来调用java,这样Zygote就从Native进入了java框架层。

源码路径:frameworks/base/core/jni/AndroidRuntime.cpp

void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
   	...
    //启动java虚拟机
    if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
        return;
    }
    onVmCreated(env);
	//为java虚拟机注册JNI方法
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }
	...
    //classname=com.android.internal.os.ZygoteInit
    classNameStr = env->NewStringUTF(className);
    assert(classNameStr != NULL);
    env->SetObjectArrayElement(strArray, 0, classNameStr);
	...
    //将className的"."替换为"/"
    char* slashClassName = toSlashClassName(className != NULL ? className : "");
    //找到ZygoteInit
    jclass startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
        ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
        /* keep going */
    } else {
        //找到ZygoteInit的main方法
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
            ALOGE("JavaVM unable to find main() in '%s'\n", className);
            /* keep going */
        } else {
            //通过JNI调用ZygoteInit的main方法
            env->CallStaticVoidMethod(startClass, startMeth, strArray);
    ...
}

分析源码得知,main方法主要做了以下四件事情:

预加载类和资源

Zygote进程启动的时候将系统的一些class(frameworks/base/config/preloaded-classes)、resource(preloaded_drawables/preloaded_color_state_lists/)等加载,后面其它进程需要使用时不需要重新加载,直接调用,加快应用启动速度。加载细节可以深入查看源码。

源码路径:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

public static void main(String[] argv) {
    ...
    String zygoteSocketName = "zygote";
    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
   }
    ...   
	//调用ZygoteServer创建两个Server端的Socket                            
    zygoteServer = new ZygoteServer(isPrimaryZygote);                            
    if (startSystemServer) {
        //启动SystemServer进程
        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;
        }
   }
   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.
   //等待AMS请求创建应用程序进程                            
   caller = zygoteServer.runSelectLoop(abiList);  
   if (caller != null) {
         caller.run();
   }                            
}
 static void preload(TimingsTraceLog bootTimingsTraceLog) {
        Log.d(TAG, "begin preload");
        bootTimingsTraceLog.traceBegin("BeginPreload");
        beginPreload();
        bootTimingsTraceLog.traceEnd(); // BeginPreload
        bootTimingsTraceLog.traceBegin("PreloadClasses");
     	//预加载类
        preloadClasses();
        bootTimingsTraceLog.traceEnd(); // PreloadClasses
        bootTimingsTraceLog.traceBegin("CacheNonBootClasspathClassLoaders");
        cacheNonBootClasspathClassLoaders();
        bootTimingsTraceLog.traceEnd(); // CacheNonBootClasspathClassLoaders
        bootTimingsTraceLog.traceBegin("PreloadResources");
     	//预加载资源
        preloadResources();
        bootTimingsTraceLog.traceEnd(); // PreloadResources
        Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs");
        nativePreloadAppProcessHALs();
        Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
        Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadGraphicsDriver");
        maybePreloadGraphicsDriver();
        Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
        preloadSharedLibraries();
        preloadTextResources();
        // Ask the WebViewFactory to do any initialization that must run in the zygote process,
        // for memory sharing purposes.
        WebViewFactory.prepareWebViewInZygote();
        endPreload();
        warmUpJcaProviders();
        Log.d(TAG, "end preload");

        sPreloadComplete = true;
    }                            
调用ZygoteServer创建两个Server端的Socket

isPrimaryZygote为true,因为socketName都为zygote,拼接的socket name为"ANDROID_SOCKET_zygote"。完成创建LocalServerSocket。在Zygote进程将SystemServer进程启动后,就会在这个server端的socket等待AMS请求Zygote进程来创建新的应用程序进程。

源码路径:frameworks/base/core/java/com/android/internal/os/ZygoteServer.java

 ZygoteServer(boolean isPrimaryZygote) {
        mUsapPoolEventFD = Zygote.getUsapPoolEventFD();

        if (isPrimaryZygote) {
            mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.PRIMARY_SOCKET_NAME);
            mUsapPoolSocket =
                    Zygote.createManagedSocketFromInitSocket(
                            Zygote.USAP_POOL_PRIMARY_SOCKET_NAME);
        } else {
            mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.SECONDARY_SOCKET_NAME);
            mUsapPoolSocket =
                    Zygote.createManagedSocketFromInitSocket(
                            Zygote.USAP_POOL_SECONDARY_SOCKET_NAME);
        }

        mUsapPoolSupported = true;
        fetchUsapPoolPolicyProps();
    }

源码路径:frameworks/base/core/java/com/android/internal/os/Zygote.java

private static final String ANDROID_SOCKET_PREFIX = "ANDROID_SOCKET_";
public static final StringPRIMARY_SOCKET_NAME  = "zygote";
static LocalServerSocket createManagedSocketFromInitSocket(String socketName) {
        int fileDesc;
    	//拼接socket名称
        final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;

        try {
            //得到socket环境变量的值
            String env = System.getenv(fullSocketName);
            //转换为文件描述符的参数
            fileDesc = Integer.parseInt(env);
        } catch (RuntimeException ex) {
            throw new RuntimeException("Socket unset or invalid: " + fullSocketName, ex);
        }

        try {
            //创建文件描述符
            FileDescriptor fd = new FileDescriptor();
            fd.setInt$(fileDesc);
            //创建server端socket
            return new LocalServerSocket(fd);
        } catch (IOException ex) {
            throw new RuntimeException(
                "Error building socket from file descriptor: " + fileDesc, ex);
        }
    }
调用Zygote的forkSystemServer方法启动SystemServer进程。

从SystemServer进程的启动参数来看,SystemServer的进程用户id和用户组id被设置为1000,并且拥有用户组1001~1010、1018、1021、1023的权限,进程名为system_server,启动类名为com.android.server.SystemServer。之后将启动参数封装,并提供给Zygote的forkSystemServer方法,nativeForkSystemServer方法会通过fork函数为当前进程创建一个子进程,就是SystemServer进程,如果forkSystemServer返回的pid=0,表示当前代码运行在新创建的子进程中,执行handleSystemServerProcess方法来处理SystemServer进程。

源码路径: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 */
        //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,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",
        };
        ZygoteArguments parsedArgs;

        int pid;

        try {
            ZygoteCommandBuffer commandBuffer = new ZygoteCommandBuffer(args);
            try {
                //参数封装
                parsedArgs = ZygoteArguments.getInstance(commandBuffer);
            } catch (EOFException e) {
                throw new AssertionError("Unexpected argument error for forking system server", e);
            }
            commandBuffer.close();
            Zygote.applyDebuggerSystemProperty(parsedArgs);
            Zygote.applyInvokeWithSystemProperty(parsedArgs);

            if (Zygote.nativeSupportsMemoryTagging()) {
                String mode = SystemProperties.get("arm64.memtag.process.system_server", "");
                if (mode.isEmpty()) {
                  /* The system server has ASYNC MTE by default, in order to allow
                   * system services to specify their own MTE level later, as you
                   * can't re-enable MTE once it's disabled. */
                  mode = SystemProperties.get("persist.arm64.memtag.default", "async");
                }
                if (mode.equals("async")) {
                    parsedArgs.mRuntimeFlags |= Zygote.MEMORY_TAG_LEVEL_ASYNC;
                } else if (mode.equals("sync")) {
                    parsedArgs.mRuntimeFlags |= Zygote.MEMORY_TAG_LEVEL_SYNC;
                } else if (!mode.equals("off")) {
                    /* When we have an invalid memory tag level, keep the current level. */
                    parsedArgs.mRuntimeFlags |= Zygote.nativeCurrentTaggingLevel();
                    Slog.e(TAG, "Unknown memory tag level for the system server: \"" + mode + "\"");
                }
            } else if (Zygote.nativeSupportsTaggedPointers()) {
                /* Enable pointer tagging in the system server. Hardware support for this is present
                 * in all ARMv8 CPUs. */
                parsedArgs.mRuntimeFlags |= Zygote.MEMORY_TAG_LEVEL_TBI;
            }

            /* Enable gwp-asan on the system server with a small probability. This is the same
             * policy as applied to native processes and system apps. */
            parsedArgs.mRuntimeFlags |= Zygote.GWP_ASAN_LEVEL_LOTTERY;

            if (shouldProfileSystemServer()) {
                parsedArgs.mRuntimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
            }

            /* Request to fork the system server process */
            //创建一个进程,SystemServer进程
            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();
            //处理SystemServer进程,SystemServer进程启动过程中详细分析
            return handleSystemServerProcess(parsedArgs);
        }

        return null;
    }    

源码路径: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;
    }
等待AMS来请求Zygote创建新的应用程序进程。

启动SystemServer进程后,会执行ZygoteServer的runSelectLoop方法。

mZygoteSocket就是第二步中创建的Server端socket,获取该socket的fd字段的值添加到fd列表socketFDs中,下面无限循环用来等待AMS请求Zygote进程创建新的应用程序进程,如果pollIndex=0,Zygote进程与AMS建立了连接,通过acceptCommandPeer方法获取ZygoteConnection对象,接着将ZygoteConnection的fd添加到fd列表,以便接收AMS发送的请求,如果poIIIndex不为0,则说明AMS向Zygote进程发送了一个创建应用进程的请求,调用ZygoteConnection类的processCommand方法创建一个新的应用程序进程。

源码路径:frameworks/base/core/java/com/android/internal/os/ZygoteServer.java

Runnable runSelectLoop(String abiList) {
        ArrayList<FileDescriptor> socketFDs = new ArrayList<>();
        ArrayList<ZygoteConnection> peers = new ArrayList<>();
		//mZygoteSocket 就是第二步创建的socket
        socketFDs.add(mZygoteSocket.getFileDescriptor());
        peers.add(null);

        mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP;
		//无限循环等待AMS的请求
        while (true) {
            fetchUsapPoolPolicyPropsWithMinInterval();
            mUsapPoolRefillAction = UsapPoolRefillAction.NONE;

            int[] usapPipeFDs = null;
            StructPollfd[] pollFDs;

            if (mUsapPoolEnabled) {
                usapPipeFDs = Zygote.getUsapPipeFDs();
                pollFDs = new StructPollfd[socketFDs.size() + 1 + usapPipeFDs.length];
            } else {
                pollFDs = new StructPollfd[socketFDs.size()];
            }

            int pollIndex = 0;
            //socketFDs转存pollFDs
            for (FileDescriptor socketFD : socketFDs) {
                pollFDs[pollIndex] = new StructPollfd();
                pollFDs[pollIndex].fd = socketFD;
                pollFDs[pollIndex].events = (short) POLLIN;
                ++pollIndex;
            }

            final int usapPoolEventFDIndex = pollIndex;

            if (mUsapPoolEnabled) {
                pollFDs[pollIndex] = new StructPollfd();
                pollFDs[pollIndex].fd = mUsapPoolEventFD;
                pollFDs[pollIndex].events = (short) POLLIN;
                ++pollIndex;

                // The usapPipeFDs array will always be filled in if the USAP Pool is enabled.
                assert usapPipeFDs != null;
                for (int usapPipeFD : usapPipeFDs) {
                    FileDescriptor managedFd = new FileDescriptor();
                    managedFd.setInt$(usapPipeFD);

                    pollFDs[pollIndex] = new StructPollfd();
                    pollFDs[pollIndex].fd = managedFd;
                    pollFDs[pollIndex].events = (short) POLLIN;
                    ++pollIndex;
                }
            }

            int pollTimeoutMs;

            if (mUsapPoolRefillTriggerTimestamp == INVALID_TIMESTAMP) {
                pollTimeoutMs = -1;
            } else {
                long elapsedTimeMs = System.currentTimeMillis() - mUsapPoolRefillTriggerTimestamp;

                if (elapsedTimeMs >= mUsapPoolRefillDelayMs) {
                    pollTimeoutMs = 0;
                    mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP;
                    mUsapPoolRefillAction = UsapPoolRefillAction.DELAYED;

                } else if (elapsedTimeMs <= 0) {
                    pollTimeoutMs = mUsapPoolRefillDelayMs;

                } else {
                    pollTimeoutMs = (int) (mUsapPoolRefillDelayMs - elapsedTimeMs);
                }
            }

            int pollReturnValue;
            try {
                pollReturnValue = Os.poll(pollFDs, pollTimeoutMs);
            } catch (ErrnoException ex) {
                throw new RuntimeException("poll failed", ex);
            }

            if (pollReturnValue == 0) {
                mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP;
                mUsapPoolRefillAction = UsapPoolRefillAction.DELAYED;

            } else {
                boolean usapPoolFDRead = false;

                while (--pollIndex >= 0) {
                    if ((pollFDs[pollIndex].revents & POLLIN) == 0) {
                        continue;
                    }

                    if (pollIndex == 0) {
                        // Zygote server socket
                        //Zygote进程与AMS建立了连接
                        ZygoteConnection newPeer = acceptCommandPeer(abiList);
                        peers.add(newPeer);
                        //ZygoteConnection的fd添加到fd列表,接收来自AMS发送的请求
                        socketFDs.add(newPeer.getFileDescriptor());
                    } else if (pollIndex < usapPoolEventFDIndex) {
                        // Session socket accepted from the Zygote server socket

                        try {
                            ZygoteConnection connection = peers.get(pollIndex);
                            boolean multipleForksOK = !isUsapPoolEnabled()
                                    && ZygoteHooks.isIndefiniteThreadSuspensionSafe
                            //AMS向Zygote进程发送一个创建应用进程的请求
                            final Runnable command =
                                    connection.processCommand(this, multipleForksOK);

                            // 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 processCommand 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 processCommand. This
                                // shows up as a regular POLLIN event in our regular processing
                                // loop.
                                if (connection.isClosedByPeer()) {
                                    connection.closeSocket();
                                    peers.remove(pollIndex);
                                    socketFDs.remove(pollIndex);
                                }
                            }
                            ...
        }
    }

Zygote的forkAndSpecialize方法会调用nativeForkAndSpecialize方法fork应用程序进程,应用程序进程创建完成,pid=0表示在子进程执行,最终执行handleChildProc方法处理应用程序进程,isZygote为false,它传递parsedArgs.mStartChildZygote,实际上应用程序进程启动没有传递"–start-child-zygote"参数,所以它为false。应用程序进程创建传递的参数会在应用程序进程启动文章中看到传递哪些参数,然后调用ZygoteInit类的zygoteInit方法。

源码路径:frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java

Runnable processCommand(ZygoteServer zygoteServer, boolean multipleOK) {
				...
                if (parsedArgs.mInvokeWith != null || parsedArgs.mStartChildZygote
                        || !multipleOK || peer.getUid() != Process.SYSTEM_UID) {
                    //获取参数
                    parsedArgs = ZygoteArguments.getInstance(argBuffer);
                    // Continue using old code for now. TODO: Handle these cases in the other path.
                    //fork app进程
                    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.mAllowlistedDataInfoList, 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);
                        } else {
                            // In the parent. A pid < 0 indicates a failure and will be handled in
                            // handleParentProc.
                            IoUtils.closeQuietly(childPipeFd);
                            childPipeFd = null;
                            handleParentProc(pid, serverPipeFd);
                            return null;
                        }
                    } finally {
                        IoUtils.closeQuietly(childPipeFd);
                        IoUtils.closeQuietly(serverPipeFd);
                    }
                } else {
                    ZygoteHooks.preFork();
                    Runnable result = Zygote.forkSimpleApps(argBuffer,
                            zygoteServer.getZygoteSocketFileDescriptor(),
                            peer.getUid(), Zygote.minChildUid(peer), parsedArgs.mNiceName);
                    if (result == null) {
                        // parent; we finished some number of forks. Result is Boolean.
                        // We already did the equivalent of handleParentProc().
                        ZygoteHooks.postForkCommon();
                        // argBuffer contains a command not understood by forksimpleApps.
                        continue;
                    } else {
                        // child; result is a Runnable.
                        zygoteServer.setForkChild();
                        Zygote.setAppProcessName(parsedArgs, TAG);  // ??? Necessary?
                        return result;
                    }
                }
            }
        }
		...
    }
private Runnable handleChildProc(ZygoteArguments parsedArgs,
            FileDescriptor pipeFd, boolean isZygote) {
        closeSocket();

        Zygote.setAppProcessName(parsedArgs, TAG);

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

zygoteInit方法中主要做了两件事,首先调用nativeZygoteInit方法去启动Binder线程池(关于Binder线程池后续会讲到),然后调用RuntimeInit类的applicationInit方法。

源码路径:frameworks\base\core\java\com\android\internal\os\ZygoteInit.java

public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
            String[] argv, ClassLoader classLoader) {
        if (RuntimeInit.DEBUG) {
            Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
        }

        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
        RuntimeInit.redirectLogStreams();

        RuntimeInit.commonInit();
    	//Binder线程池启动
        ZygoteInit.nativeZygoteInit();
        return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
                classLoader);
}

applicationInit方法中开始设置参数,并获取应用程序进程的启动类,findStaticMain方法中通过反射获取启动类的main方法,返回MethodAndArgsCaller,最终在ZygoteInit类的main方法中,调用其run方法。

源码路径:frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
            String[] argv, ClassLoader classLoader) {
        // If the application calls System.exit(), terminate the process
        // immediately without running any shutdown hooks.  It is not possible to
        // shutdown an Android application gracefully.  Among other things, the
        // Android runtime shutdown hooks close the Binder driver, which can cause
        // leftover running threads to crash before the process actually exits.
        nativeSetExitWithoutCleanup(true);

        VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
        VMRuntime.getRuntime().setDisabledCompatChanges(disabledCompatChanges);

        final Arguments args = new Arguments(argv);

        // The end of of the RuntimeInit event (see #zygoteInit).
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

        // Remaining arguments are passed to the start class's static main
        return 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 {
            //main方法反射
            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);
        }
        return new MethodAndArgsCaller(m, argv);
}
static class MethodAndArgsCaller implements Runnable {
        /** method to call */
        private final Method mMethod;

        /** argument array */
        private final String[] mArgs;

        public MethodAndArgsCaller(Method method, String[] args) {
            mMethod = method;
            mArgs = args;
        }

        public void run() {
            try {
                mMethod.invoke(null, new Object[] { mArgs });
        ...

补充

在Zygote进程启动过程第中,等待AMS来请求Zygote进程创建新的应用程序进程,其中有说到Binder线程池通过ZygoteInit类的nativeZygoteInit方法启动,下面分析下Binder线程池的启动过程。

Binder线程池启动过程

Binder线程池在Android中扮演着重要的角色,它是Android操作系统的一种进程间通信(IPC)机制。从源码可以看出nativeZygoteInit方法是一个JNI方法(关于JNI,请查看之前文章使用Android Studio开发第一个NDK程序),

源码路径:frameworks\base\core\java\com\android\internal\os\ZygoteInit.java

public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
            String[] argv, ClassLoader classLoader) {
        if (RuntimeInit.DEBUG) {
            Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
        }

        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
        RuntimeInit.redirectLogStreams();

        RuntimeInit.commonInit();
        ZygoteInit.nativeZygoteInit();
        return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
                classLoader);
    } 
private static native void nativeZygoteInit();

它对应的C函数是什么呢?在AndroidRuntime类中,从JNINativeMethod数组中可以得知它所对应的函数为com_android_internal_os_ZygoteInit_nativeZygoteInit,在其函数中,gCurRuntime为AndroidRuntime类型的指针,在AndroidRuntime初始化时就创建了,

源码路径:frameworks\base\core\jni\AndroidRuntime.cpp

static AndroidRuntime* gCurRuntime = NULL;
int register_com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env)
{
    const JNINativeMethod methods[] = {
        { "nativeZygoteInit", "()V",
            (void*) com_android_internal_os_ZygoteInit_nativeZygoteInit },
    };
    return jniRegisterNativeMethods(env, "com/android/internal/os/ZygoteInit",
        methods, NELEM(methods));
}
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
    gCurRuntime->onZygoteInit();
}
AndroidRuntime::AndroidRuntime(char* argBlockStart, const size_t argBlockLength) :
        mExitWithoutCleanup(false),
        mArgBlockStart(argBlockStart),
        mArgBlockLength(argBlockLength)
{
    init_android_graphics();

    // Pre-allocate enough space to hold a fair number of options.
    mOptions.setCapacity(20);

    assert(gCurRuntime == NULL);        // one per process
    gCurRuntime = this;
}

AppRuntime继承自AndroidRuntime,AppRuntime创建时会调用AndroidRuntime的构造函数,gCurRuntime就会被初始化,它指向AppRuntime,查看AppRuntime的onZygoteInit函数,AppRuntime在app_main类中实现,onZygoteInit函数中调用ProcessState类的

startThreadPool函数启动Binder线程池。

源码路径:frameworks\base\cmds\app_process\app_main.cpp

class AppRuntime : public AndroidRuntime
{
    virtual void onZygoteInit()
    {
        sp<ProcessState> proc = ProcessState::self();
        ALOGV("App process: starting thread pool.\n");
        proc->startThreadPool();
    }
}

支持Binder通信的进程都有一个ProcessState类,它里面有一个mThreadPoolStarted变量,用来表示Binder线程池是否已经被启动过,默认值为false,每次调用startThreadPool函数都会先检查这个变量,确保Binder 线程池只会被启动一次,如果未启动,则会将mThreadPoolStarted设置为true,然后调用spawnPooledThread函数来创建线程池的第一个线程,也就是线程池的主线程。可以看到Binder线程池为一个PoolThread,然后调用run函数来启动一个新的线程。

PoolThread类继承了Thread类,调用IPCThreadState的joinThreadPool函数,将当前线程注册到Binder驱动程序中,这样创建的线程就被加入到Binder线程池中,新创建的应用程序进程就可以支持Binder进程间通信了。

源码路径:frameworks/native/libs/binder/ProcessState.cpp

void ProcessState::startThreadPool(
{
    AutoMutex _l(mLock);
    if (!mThreadPoolStarted) {
        if (mMaxThreads == 0) {
            ALOGW("Extra binder thread started, but 0 threads requested. Do not use "
                  "*startThreadPool when zero threads are requested.");
        }

        mThreadPoolStarted = true;
        spawnPooledThread(true);
    }
}
void ProcessState::spawnPooledThread(bool isMain)
{
    if (mThreadPoolStarted) {
        String8 name = makeBinderThreadName();
        ALOGV("Spawning new pooled thread, name=%s\n", name.string());
        sp<Thread> t = sp<PoolThread>::make(isMain);
        t->run(name.string());
    }
}
class PoolThread : public Thread
{
public:
    explicit PoolThread(bool isMain)
        : mIsMain(isMain)
    {
    }

protected:
    virtual bool threadLoop()
    {
        IPCThreadState::self()->joinThreadPool(mIsMain);
        return false;
    }

    const bool mIsMain;
};

总结

Zygote进程启动过程的时序图如下:

Zygote进程启动时序

Zygote进程启动主要做了如下事情:

  1. 创建AndroidRuntime并调用start函数,启动Zygote进程。
  2. 创建Java虚拟机并为Java虚拟机注册JNI方法。
  3. 通过JNI调用ZygoteInit的main函数进入Zygote的Java框架层。、
  4. 启动SystemServer进程。
  5. 注册socket,并通过runSelectLoop方法等待AMS的请求来创建新的应用程序进程。
Android Framework学习三:zygote剖析 zygote 进程启动:Zygote 是 Android 系统中一个重要的进程,是所有 Java 应用程序进程的孵化器 ,它的启动是整个流程的开端。 随后进入app_main.cpp中的main()函数,这是 Zygote 进程在 C++ 层面启动的入口函数。runtime.start () 启动 ZygoteInit:调用runtime.start()函数来启动ZygoteInit。这是 Zygote 进程启动过程中的关键步骤,它会进一步调用一系列函数来完成虚拟机和 JNI 相关的初始化 阅读详情

相关推荐

基于Android 14系统启动流程之zygote进程启动解析 (详细分析从kernel启动到zygote启动完了的过程)

本篇文章主要讲解zygote是如何启动的,从内核kernel启动开始,一直贯穿到java层代码,包括以下几部分: 1、init 进程的启动时机 2、init 进程都做了哪些事情 3、zygote进程启动的时机,都做了哪些内容 4、java代码是如何运行的 5、简单画了函数之间的调用关系。

qq_15125719的博客 2359

Android Zygote

1.Zygote Zygote译为“受精卵”,是Android中SystemServer和几乎所有Java应用的孵化器。SystemServer和Java应用的父进程都是zygote。zygote是一个很重要的服务进程,没有zygote就没有Android,Android的启动也离不开zygote。 zygote的启动: zygote是服务进程的别名,zygote是由rc文件定义init启动的服务。从rc文件中可以看出: ①zygote的进程优先级是最高的,priority被设成-20,主要是.

zenmela2011的专栏 9681

Android Framework分析Zygote进程的启动过程

在该方法中,Zygote进程会不断地监听ServerSocket对象是否有新的socket连接请求,并在接收到新的socket连接请求时,调用ZygoteInit.forkAndSpecialize()方法来创建新的应用进程,并通过socket文件描述符的方式将新进程启动起来。如上所示,新应用进程中会通过forkAndSpecialize()方法创建一个应用类加载器,在运行时期,Zygote进程将通过Socket描述符的方式将应用进程类加载器传递给应用进程,并启动应用进程。下面我们将逐一进行讲解。

工宗浩生财指南针 513

安卓Zygote详解

一、Zygote, 意为“受精卵”,Android系统中几乎所有的应用进程都是由Zygote进程孵化出来的,Java环境也是由Zygote创建起来的,它建立了我们app运行所需要的环境,是app的祖先,因此,分析它的启动以及内部逻辑显得非常有必要。 *Android系统是基于Linux内核的,而在Linux系统中,所有的进程都是init进程的子孙进程,也就是说,所有的进程都是直接或者间接

Leonban的博客 7368

Zygote Secondary:加速应用启动的未来之路

再次强调 Zygote Secondary 作为一项重要的进程管理技术Zygote Secondary 技术作为一种创新的进程管理技术,在 Android 平台上发挥着重要的作用。通过共享虚拟机实例和资源管理,它大大提高了应用程序的启动速度和内存使用效率。这对于提升用户体验和应用程序竞争力至关重要。鼓励开发者和系统优化者积极采用并支持 Zygote Secondary 的发展作为开发者和系统优化者,我们应该积极采用和支持 Zygote Secondary 技术的发展。

虎哥LoveDroid 780

H.264 Profile与Level详解:如何为不同应用场景选择合适的编码配置

本文深入解析了H.264编码标准中的Profile与Level概念,指导开发者如何为不同应用场景选择合适的配置。文章对比了Baseline、Main和High三大Profile的特性与适用场景,并解释了Level如何限定视频的分辨率、帧率与码率上限。通过实战指南,帮助读者在视频通话、在线点播和专业制作等场景中,平衡画质、兼容性与性能,实现高效编码。

rgv2345678的博客 238

【Android】系统启动流程分析 —— Zygote 进程启动过程

本文基于 Android 14.0.0_r2 的系统启动流程分析。

Creativity + Efficiency = Success 4653

别再死记硬背参数了!用ADS手把手教你仿真一个4GHz镜像抑制混频器(附完整工程文件)

本文详细解析了4GHz镜像抑制混频器的ADS仿真全流程,从理论到实践,涵盖混频器设计基础、ADS工程搭建、二极管选型、非线性仿真及性能优化。通过实战案例,帮助工程师掌握关键参数平衡与调试技巧,提升射频电路设计效率。

weixin_42552716的博客 338

Android系统进程Zygote启动过程的源代码分析

在Android系统中,所有的应用程序进程以及系统服务进程SystemServer都是由Zygote进程孕育(fork)出来的,这也许就是为什么要把它称为Zygote(受精卵)的原因吧。由于Zygote进程在Android系统中有着如此重要的地位,本文将详细分析它的启动过程。        在前面一篇文章Android应用程序进程启动过程的源代码分析中,我们看到了,当ActivityManager

老罗的Android之旅 12万+

NVIDIA Orin AGX开发环境搭建避坑指南:从Ubuntu 22.04到ROS2完整配置流程

本文详细介绍了NVIDIA Orin AGX开发环境搭建的全流程,从Ubuntu 22.04系统安装到ROS2深度优化,涵盖驱动部署、CUDA环境配置、散热与功耗管理等关键步骤。特别针对Orin AGX的特性提供了实用避坑指南和性能优化技巧,帮助开发者高效完成开发环境配置。

weixin_28340315的博客 451

PyCharm旧版本下载地址

快捷找到PyCharm历史版本下载地址

piaopiaolanghua的专栏 4434

Android zygote 进程的启动过程分析

zygote进程在 Android 开发中属于比较底层的内容,然而要透彻的理解 AMS、WMS 和 IPC 等,不可避免的要先理解zogyte进程,因此本文即作为对自己的学习记录,也想分享出来和遇到同样问题的读者交流。

布莱克‌ 5930

Java实现双色球&大乐透随机选号算法——原理详解与代码实战

掌握核心语法:集合操作、随机数生成、排序。贴近实际场景:将编程知识应用于生活问题的解决。

wangchl0932的博客 4974

Android Zygote进程启动过程

Zygote是由init进程启动的。 而在Android系统中,Dalvik/ART虚拟机、应用程序进程以及运行系统的关键服务的SystemServer进程都是由Zygote进程(孵化器)来创建的。 ...

朱豪凯的博客 706

手把手教你学PCIE-- 热插拔电路设计与实现方案

PCIe热插拔(Hot-Plug)技术允许用户在系统运行时安全地插入或移除设备,而无需重启系统。本文将深入讲解热插拔电路的设计要点、关键器件选型及信号协议规范,涵盖机械结构、电气保护和电源管理三大核心模块。​。

MHD0815的博客 440

uniapp - 热更新提示:WGT安装包中manifest.json文件不存在 | unexpected EOF!报错详细解决,完美搞定WGT安装包中WWW目录下manifest.json不存在问题

uniapp,安卓android,苹果ios,热更新,热更新code:-1202报错,,WGT热更新报错,uniapp热更新wgt出现报错manifest.json文件不存,uniapp安卓苹果软件热更新时出现错误unexpected EOF!如何解决,怎么解决热更新wgt报错,app新版本下载安装报错WGT安装包中manifest.json文件不存在,WGT安装包中WWW目录下manifest.json不存在,uniapp热更新报错安装失败[-1201]:WGT/WGTU文件格式错误,uniapp-wgt

✅ 精选推荐文章 1万+

android zygote进程启动到SystemServer进程启动过程

首先,我们来看android手机启动过程图: &amp;amp;amp;lt;插入android手机启动流程图&amp;amp;amp;gt; android手机通电后,系统启动加载器会从ROM中加载引导程序到RAM,然后初始化硬件参数等必要资源,接着会加载Linux内核到RAM,Kernel接着会启动Init祖先进程,在Init进程中会解析init.rc等配置文件,接着就会开始启动zygote进程。 我们直接从启动zygote的函数出发,探究...

luoyingxing的博客 1496

基于 C# 实现 RTSP 摄像头监控分屏系统:从流媒体获取到多画面显示

通过本文的讲解,我们介绍了如何在 C# 中实现 RTSP 摄像头监控分屏系统。我们使用了FFmpeg和VLC两种不同的方法来获取和解码 RTSP 流,并通过PictureBox控件和控件实现了分屏布局。两种解码方案都非常强大,可以根据实际需求选择最适合的方案。通过这种方式,您可以轻松地在 C# 中集成 RTSP 流,并将多个摄像头的视频流实时显示在同一屏幕上,进行监控和分析。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 2307

Android zygote进程启动过程

安卓zygote进程启动过程

qq_36063677的博客 1267

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Android系统启动流程(二)解析Zygote进程启动过程

上一篇文章我们分析了init进程,init进程中主要做了三件事,其中一件就是创建了Zygote进程,那么Zygote进程是什么,它做了哪些事呢?这篇文章会给你这些问题的答案。

Android进阶三部曲 - 刘望舒 1万+

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Zygote进程启动过程

1.Zygote简介 在Android系统中,DVM(Dalvik虚拟机)、应用程序进程以及运行系统关键服务的SystemServer进程都是由Zygote进程来创建的,我们也将它称为孵化器。它通过fork(复制进程)的形式来创建应用程序进程和SystemServer进程,由于Zygote进程在启动时会创建DVM,因此通过fork而创建的应用程序进程和SystemServer进程可以在内部获取一个DVM的实例拷贝。 2.源码分析 frameworks\base\cmds\app_process\app

xiaowang_lj的博客 611

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Zygote和System进程的启动过程

韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha #Zygote和System进程的启动过程 ##init脚本的启动 +------------+ +-------+ +-----------+ |Linux Kernel+--> |init.rc+-> |app_process| +------------+

韩梦飞沙_韩亚飞 199

Init进程启动Zygote进程的过程

Android系统启动时在加载完内核之后会启动Init进程,Init进程的启动过程中会读取根目录下的脚本文件Init.rc,以便将Zygote进程启动起来。       //Android系统在加载内核之后会启动init进程,以下为Init进程的main函数 int main(int argc, char **argv) { int fd_count = 0; st

TiuTiu Zone 924

Android系统启动(二) — Zygote进程启动过程

在Android系统中,DVMDalvik虚拟机)和ART,系统服务进程以及应用程序进程都是由Zygote进程来创建的(而Native程序,也就是C/C++开发的程序则是由init进程创建启动的)。Zygote进程也称孵化器,通过fork(复制进程)的形式来创建应用程序进程和进程,由于Zygote进程在启动时会创建DVM或者ART,因此通过fork而创建的应用程序进程和进程可以在内部获取一个DVM或者ART的实例副本。Zygote进程是在init进程启动时创建的,起初,Zygote进程的名称并不是。

xingyu19911016的博客 1645
上一篇: Android开机动画启动流程
下一篇: SystemServer 进程启动过程
八归少年
八归少年 新星创作者: 操作系统技术领域 新星创作者: 操作系统技术领域
博客等级 码龄9年 9011粉丝 63原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

八归少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值