“This is the second day of my participation in the August More Text Challenge. For details, see: August More Text Challenge.”

preface

When asked about Zygote, what do you think the interviewer wants to hear and what do you really want to ask? Let’s analyze this problem through the following points!

  • Learn what Zygote does
  • Familiar with the start-up process of Zygote
  • Deep understanding of how Zygote works

Let’s break it down

First, the role of Zygote

The effects of Zygote are divided into two points:

  • Start the SystemServer
  • Incubation application process

OK if you answer both of those questions. Probably most of you will be able to answer the second one, but the first one is not so clear. SystemServer is also started by Zygote, because SystemServer needs to use the system resources prepared by Zygote, including:

Inherits directly from Zygote without needing to reload, which is a big performance boost.

Second, the start-up process of Zygote

2.1 Three-stage startup

Before talking about the startup process of Zygote, ** first make clear a concept: the startup of three stages, ** this can be understood as the common routine in Android process startup, divided into three steps:

LOOP accepts and processes messages. The source of a message can be a socket, MessageQueue, or Binder. However, no matter where the message comes from, the entire process is to receive and process the message. This start three, it is not only Zygote process is such, as long as there is an independent process, such as the system service process, their own application process are so.

2.2 How does the Zygote process start?

The Zygote process is started by the init process, which is the first process in user space after Linux is started.

  1. Linux starts the init process
  2. Load the init.rc configuration file after the init process starts

  1. Start the system services defined in the configuration file. The Zygote service is defined in the configuration

  1. At the same time start the service in addition to Zygote there are some other system services will be started, such as ServiceManager process, it is started through fork+execve system call

2.2.1Load the startup configuration for Zygote

${ro.zygote}.rc, init.zygoteXX,XX refers to 32 or 64, so we can just look at init.zygote32.rc. The configuration file is quite long, so I made an intercept here to preserve the Zygot related parts.

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server    
class main    
socket zygote stream 660 root system    
onrestart write /sys/android_power/request_state wake    
onrestart write /sys/power/state on    
onrestart restart audioserver    
writepid /dev/cpuset/foreground/tasks
Copy the code
  • Service zygote: specifies the process name,
  • /system/bin/app_process: The path of the executable program for init process fork, execve calls
  • -Xzygote /system/bin –zygote –start-system-server indicates the parameter

2.2.2Start the process

There are two ways to start a process:

Fork +handle

pid_t pid = fork();
if (pid == 0) {// child process
} else {
  // parent process
}
Copy the code

Fork +execve

pid_t pid = fork();
if (pid == 0) {
  // child process
  execve(path, argv, env);
} else {
  // parent process
}
Copy the code

They both look similar. First, the fork function is called to create the child process. This function returns twice, once for the child process and once for the parent process. The differences are:

  • The pid returned by the child process is 0, but the pid returned by the parent process is the pid of the child process, so you can distinguish between the child process and the parent process by judging the PID
  • By default, the child process inherits all resources from the parent process, but when a binary program is loaded through Execve, the parent process’s resources are cleared

2.2.3Signal processing -SIGCHLD

When the parent fork the child, the parent needs to pay attention to this signal. When the child dies, the parent receives the SIGCHLD, and the parent can do some processing. For example, if the Zygote process is dead, the parent init process will receive a signal to restart the Zygote process.

Three, the Zygote process startup principle

After the Zygote process is started, it executes the execve system call. It executes the main function in the binary executable program written in C++ as the entry point, and then runs in the Java layer!

Take a look at the processing flow for the Native layer

In the app_main. CPP file, androidRuntime. CPP file. We can find several major function names

int main(int argc,char *argv[]){
   JavaVM *jvm;
   JNIEnv *env;
   JNI_CreateJavaVM(&jvm,(void**)&env,&vm_args); // Create a Java virtual machine
   jclass clazz = env->FindClass("ZygoteInit"); // Find the Java class ZygoteInit
   jmethodID method = env->GetStaticMethodID(clazz,"Main"."[Ljava/lang/String;)V"); // Find the static function of Main in ZygoteInit class
   env->CallStaticVoidMethod(clazz,method,args); // Call the main function
   jvm->DestroyJavaVM(a); }Copy the code

Based on the above code, you will find that in our application you can make JNI calls directly, without creating a virtual machine. Because the application process is Zygote process hatched out, inherited the parent process of the virtual machine, only need to reset the data.

Next, look at the Java layer. See the main method in the ZygoteInit file

  1. Preload resources, such as common class libraries, topic resources, and some shared libraries

  1. Start the SystemServer process

  1. Into the Socket of the Loop cycle will see ZygoteServer. RunSelectLoop (…). call
boolean runOnce(a) {
	String[] args = readArgumentList(); // Read the parameter list
	int pid = Zygote.forkAndSpecialize(); // Start the child process according to the read parameters
	if(pid == 0) {
		//in child
		// Execute the ActivityThread entry function (main)handleChildProc(args,...) ;return true; }}Copy the code

Four,

Zygote startup process needs the following two main problems

  1. Zygote fork must be single threaded
  2. Zygote IPC uses socket

Read three things ❤️

If you found this post helpful, I’d like to invite you to do three small favors for me:

  1. Likes, retweets, and your “likes and comments” are what drive me to create.
  2. Follow the public account “A Feng’s architecture Notes” and share original knowledge irregularly.
  3. In the meantime, look forward to a follow-up article at ing🚀