Home

The previous blog post looked at Android’s init process. Android has its own init system, which uses rc files to declare what services to start and when. One of the primary rc file is init.rc. This configuration file starts various important system services such as ueventd, logd, netd, zygote, console, etc.

In this post, we focus on the zygote process.

app_process

The service zygote is declared in init.zygote32.rc.

The command that is used to run zygote is:

/system/bin/app_process -Xzygote /system/bin --zygote --start-system-server

This is shell syntax - run the /system/bin/app_process binary with the provided arguments. 1

At a high level, app_process has two main responsibilities:

  1. initialize the Android runtime, and

    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
  2. use the runtime to start zygote via its main method

    runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    
    // calls into AndroidRuntime.cpp
    
    jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
    // ...
    env->CallStaticVoidMethod(startClass, startMeth, strArray);

The Android Runtime refers to ART and Dalvik - they run Android apps and some system services.

Zygote is the base process from which every other Android process is forked from. This forking model helps to conserve memory on mobile devices, because a lot of resources can be shared.

zygote

The entry point to zygote is in the main method of ZygoteInit.

Zygote has a number of very important responsibilities:

  1. preloading shared resources,

    preloadClasses();
    // ...
    preloadResources();
    // ...
    preloadOpenGL();
    // ...
    preloadSharedLibraries();
    preloadTextResources();
    // ...
  2. knowing when to fork off a system server process by looking at the arguments that app_process passed to it,

  3. delegating to a ZygoteServer which then listens to commands on a socket

As mentioned, to save memory, processes on Android try to share as much resources as possible. For example, system class/dex files (like String) cannot change on a system, so those important code files are preloaded so every process can share them2. Also, resources like drawables and styles across the system can be shared by process as well.

To fork off a system server, ZygoteInit delegates to Zygote, calling forkSystemServer:

pid = Zygote.forkSystemServer(/* lots of args */);

This is in turn implemented natively via Android’s Native Development Kit (NDK):

static jint com_android_internal_os_Zygote_nativeForkSystemServer(/* lots of args */) { /* body */  }

At the end of all these, the initial single ZygoteInit process is now running as a ZygoteServer3, and an additional process, forked from ZygoteInit, is running as system server.

In the next blog post we will look at the system server, one of the first and most important system services to be started.


  1. The source of app_process can be found in frameworks/base/cmds/app_process.cpp. and the comments in source goes into more details about what the arguments are used for.↩︎

  2. the list of classes that zygote preloads is hard-coded to be /system/etc/preloaded-classes, and this file i found in frameworks/base/preloaded-classes.↩︎

  3. The ZygoteServer will poll for events on file descriptors and dispatch commands appropriately.↩︎