Understanding zygote

On Android, Zygote is a native process that is the parent of all application processes. Zygote, on the other hand, is the Linux user space’s first process, init, which is forked and started.

role

When zygote process starts, it creates an instance of Dalvik VM. Each time a new application process hatches, the Dalvik VM instance is copied to the new application process, so that each application process has an independent instance of Dalvik VM.

The Zygote process has two main functions:

  • Start the SystemServer.
  • Incubate the application process.

Start the process

Start the entrance

Zygote is started and created as a service in init by parsing the init.zygote.rc configuration file.

Take init.zygote32.rc as an example:

The script on
// system\core\rootdir\init.zygote32.rc
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
    class main
    priority- 20user root
    group root readproc reserved_disk
    socket zygote stream 660 root system
    socket usap_pool_primary stream 660 root system
    onrestart write /sys/power/state on
    onrestart restart audioserver
    onrestart restart cameraserver
    onrestart restart media
    onrestart restart netd
    onrestart restart wificond
    writepid /dev/cpuset/foreground/tasks
Copy the code

This script requires the init process to create a process named zygote that executes the program “/system/bin/app_process”. It also creates a socket resource for the Zygote process (for interprocess communication, through which ActivityManagerService requests the Zygote process to fork an application process).

The following **–zygote** is an argument that indicates that the zygote process has been started. This parameter is used in the main function of app_process to decide whether to execute ZygoteInit or the Java class.

The boot process

The zygote program is system/bin/app_process, and its source code is in frameworks/base/ CMDS /app_process/app_main.cpp

App_main::main
int main(int argc, char* const argv[])
{...while (i < argc) {
        const char* arg = argv[i++];
        if (strcmp(arg, "--zygote") = =0) {// Whether there is a --zygote parameter. This is the parameter to start the Zygote process
            zygote = true;
			// Process name, set to zygote
            niceName = ZYGOTE_NICE_NAME;
        } else if (strcmp(arg, "--start-system-server") = =0) {// Whether there is --start-system-server
            startSystemServer = true; .if (zygote) {
		// The most important way... If it is a Zygote process, ZygoteInit is started.
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } else if (className) {
        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."); }}Copy the code
AndroidRuntime::start
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{... JNIEnv* env;// The key method is to create a VM. The argument is a pointer, which can be used to get the returned value. You can use env to interact with the Java layer
    if(startVm(&mJavaVM, &env, zygote) ! =0) {
        return;
    }
    onVmCreated(env);
    // Register some JNI functions for the vm (system so library, user-defined so library, loading function, etc.)
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }

    	// Find the class's main method and call it. If it's zygote, it's going to start the main method of the ZygoteInit class
        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 {
        	// Call main. After calling Java methods through JNI, Zygote(Native layer) enters the Java world, thus opening up the Java world in Android.
            env->CallStaticVoidMethod(startClass, startMeth, strArray);
}
Copy the code
App_main.main
  AndroidRuntime.start
    startVm// Create a VM
    startReg// Register JNI functions
    ZygoteInit.main// This is the Java layer
        registerZygoteSocket// Set up IPC communication mechanism
        preload// Preload classes and resources
        startSystemServer/ / start system_server
        runSelectLoop// Wait for a request for process creation
Copy the code

Source code address: / frameworks/base/CMDS app_process/App_main. CPP (including AppRuntime class)/frameworks/base/core/jni/AndroidRuntime CPP /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java /frameworks/base/core/java/com/android/internal/os/Zygote.java /frameworks/base/core/java/android/net/LocalServerSocket.java

During the Zygote process startup, in addition to creating a Dalvik VM instance, the Java runtime library will be loaded into the process and some JNI methods of the Android core classes will be registered in the Dalvik VM instance.

When the Zygote process initializes, it starts the virtualization and loads some system resources. When zygote forks a child process, it inherits a working VIRTUAL machine and various system resources, leaving only the bytecode loaded with APK files to run the program.

Java applications cannot run as local processes and must run in a separate virtual machine. If you restart the virtual machine every time, you are sure to slow down the startup of your application.

Note: When an APK application process is incubated by the Zygote process, it not only gets a copy of the Dalvik VIRTUAL machine instance, but also shares the Java runtime library with Zygote.

reference

Blog.csdn.net/qq_24451593…

Blog.csdn.net/tfygg/artic…

Blog.csdn.net/chz429/arti…

Source code analysis project address: github.com/kailaisi/an…

Synchronous public number [open Ken]