Android startup tour - zygote
2017-09-24 11:30
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:
initialize the Android runtime, and
use the runtime to start zygote via its
main
method
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:
preloading shared resources,
knowing when to fork off a system server process by looking at the arguments that
app_process
passed to it,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:
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.
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.↩︎
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.↩︎The ZygoteServer will poll for events on file descriptors and dispatch commands appropriately.↩︎