Android

Detailed explanation of Zygote

2025-10-27

The original intention and core values of Zygote's design

Before understanding how Zygote works, it is important to first understand why it exists.

1. Problem to be solved:

Imagine that without Zygote, the system would need to:

Start a JVM separately

Reload all classes of the Android Framework (such as Activity, View, Context, etc., thousands of classes)

Reload system resources (such as system themes, strings, etc.)

This can lead to extremely slow application startup and huge memory consumption (each process has a copy of the same class and resources).

2. Zygote's solution:

Zygote adopts the classic "preload+fork" mode, with the core ideas of "space for time" and "shared memory".

Preloading: At the beginning of system startup, the Zygote process completes the loading of all the classes and resources required by the App in one go.

Process Incubation: When a new app needs to be launched, Zygote splits itself through the fork() system call to create a child process. This child process naturally inherits all the memory states already loaded by the parent process (Zygote).

The Startup and Initialization Process of Zygote

The launch of Zygote is a clear chain:

Init process ->parse init.rc ->start appsprocess ->execute ZygoteIt.java

Detailed steps:

1.Starting from the Init process, there is a definition similar to the following in init.zygote32.rc or similar configuration files:

//img.enjoy4fun.com/news_icon/d3vlrkldm8bc72tp8r60.png

Service zygote: defines a service called "zygote".

/System/bin/app_decess: This is the true executable file of Zygote. It is not a regular JAR, but a native program that can start the Android runtime environment.

--Zygote -- start system server: parameter that tells app_decess to start in Zygote mode and incubate the System Server.

2.Create a virtual machine and preload it:

After app_decess is executed, the first Android Runtime (ART) instance will be created.

Then enter the Java world and execute the main() method of ZygoteIt.java.

In the main() method, Zygote performs a heavy but crucial task: preloading.

PreloadClasses: Call preloadClasses(). It will read the/system/etc/preloaded classes file (a list of thousands of commonly used classes) and then load them one by one using Class. forName(). This includes all Android Framework classes.

PreloadResources: Call preloadResources(). This will load the system's general resources, such as drawables and XML configurations in framework-res.xpk.

Preloading shared libraries: Load some necessary JNI libraries, such as libandroid.so, etc.

3. Start System Server:

After preloading is complete, Zygote forks the first and most important subprocess - System Server.

System Server hosts all critical system services in Android, such as AMS, WMS, PMS, etc.

4. Enter the loop and listen to Socket:

After incubating the System Server, the Zygote parent process will close unnecessary Socket replicas.

Then call the runSelectLoop() method, enter an infinite loop, listen to the socket connection on/dev/socket/zygote, and wait for the request from the ActivityManagerService to start a new application.

The detailed principle of Zygote incubating new application processes

This is the most exquisite part of Zygote. When the user clicks on the app icon:

1. AMS sends a request:

The Activity Manager Service has decided to launch an application, but it does not have the authority to create new processes on its own.

AMS sends a request message to Zygote's Socket to start a new process using the Process. start() method. This message contains necessary parameters for the new process, such as UID, GID, main class name (usually android. app. ActiveThread), parameters, etc.

2. Zygote handles requests:

When a Zygote process detects a Socket connection in runSelectLoop(), it forks itself and creates a child process.

Key point: This subprocess is a complete copy of Zygote and inherits:

The ART virtual machine that has already been initialized.

All preloaded Java classes.

All preloaded resources and shared libraries.

The system's LD_LIBRRY-PATH and other environments.

3. Specialization of child processes:

Although the child process inherits everything, it needs to become an independent App process rather than another Zygote.

After fork(), the child process will:

Close unnecessary Socket connections inherited from Zygote.

Set the process name (from "zygote" to the package name, such as com. example. app).

Set UID/GID for application sandbox isolation.

Finally, call ZygoteInit. zygoteInit() ->RuntimeInit. applicationInit() ->find the mainClass (that is, ActivityThread) passed from AMS, and execute its main() method.

ActiveThread. main() is called, which means that the main thread (UI thread) of the App process officially starts running. It creates an Application object and then launches the main Activity.

Zygote's core mechanism: copy on write

This is the cornerstone of Zygote's ability to save memory.

Principle: When Zygote creates a child process through fork(), the kernel does not immediately copy the memory space of the parent process to the child process. On the contrary, it allows the parent and child processes to share the same physical memory page and marks these memory pages as read-only.

Copy on Write: When a parent or child process attempts to modify a memory page, the kernel catches this "write operation" exception and only copies a copy of the memory page for the process attempting to modify, allowing it to make modifications on this copy. And other memory pages that are still read-only continue to be shared.

The huge advantages brought by:

Memory efficiency: 100 apps may share 90% of Framework code and resources. If there is no COW, the memory usage will be 100 * Zygote memory. With COW, the memory usage is close to Zygote's memory+100 * (each app's private memory).

Startup speed: Because there is no need to reload classes and resources, fork() of a process and "specialization" it is much faster than starting a JVM from scratch and loading everything.

Variations and Evolution of Zygote

WebView Zygote:

In order to allow WebView to also enjoy the benefits of preloading and achieve isolation from the main process of the app, Android introduced the independent webview_zygote. It preloads WebView related code specifically designed to incubate the process of rendering web content.

Apply Zygote:

Starting from Android 10, the "Zygote application" was introduced. It allows an application to initialize its own Zygote process in advance at system startup, so that when a component of the application needs to be launched, it can be quickly forked from its Zygote application, further accelerating the startup speed.

Zygote's design is a classic trade-off in the Android system architecture. It trades in a complex boot time preloading process for the ultimate boot speed and memory efficiency of all applications during runtime. This design perfectly fits the limited resources of mobile devices but requires quick response.

Understanding Zygote also has guiding significance for us to optimize application startup. For example, we know that Zygote has preloaded the Framework class, so the initialization of the application and the first activity should be as lightweight as possible, avoiding heavy operations on the main thread, in order to maximize the startup advantages brought by Zygote. "

more stories
See more