Android from the foundation · Puzzle 3 of 6
Zygote is why apps start fast
One process, started at boot, preloads ART and the framework. Every app is forked from it and shares its memory until it writes.
The problem
In puzzle 2, ART moved into every house. But starting ART and loading the thousands of framework classes takes seconds. If every app launch did that from scratch, every tap on an icon would be slow, and every app would hold its own copy of the same framework in memory.
See it
At boot, Android starts one process, Zygote, and loads ART and the framework into its memory once. Then it waits.
Step 1 of 4You tap an icon. Zygote forks: the kernel makes a new process that starts as a copy of Zygote, switches it to your app's UID, and loads your code.
Step 2 of 4The new process doesn't get its own copy of the framework: it shares Zygote's memory pages. So does every other app. Predict: what if your app changes a shared page?
Step 3 of 4Only then does the kernel copy that one page for your app: copy-on-write. Everything you don't change stays shared.
Step 4 of 4
The building block
The kernel hands out memory in small fixed-size blocks called pages. To fork is to ask the kernel for a new process that starts as a copy of an existing one. The copy is cheap because the kernel doesn't duplicate the pages: parent and child share them, and a page is only copied when one of them writes to it (copy-on-write).
Zygote ("the first cell") starts at boot, loads ART and the common framework code, then waits. It also forks system_server, the town hall. When you launch an app, system_server asks Zygote to fork; the child switches to the app's UID and loads the app's code.
In the source, ZygoteInit.main()Zygote's main: preload the framework, fork system_server, then wait for "fork an app" requests. 817 public static void main(String[] argv) {
…
885 preload(bootTimingsTraceLog);
…
905 Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
…
919 caller = zygoteServer.runSelectLoop(abiList);ZygoteInit.java, line 817 · AOSP frameworks/base ↗ does exactly this: preload, start system_server, then wait for "fork an app" requests.
In practice: cold, warm, hot start
Your app has one Application object per process; its Application.onCreate() runs before any screen exists. Then come the screens (Activities).
- Cold start: no process yet. Fork from Zygote, create the Application, then the first Activity.
- Warm start: the process is alive, but the Activity has to be created again.
- Hot start: process and Activity are alive; the app just comes back to the front. (Nothing to do with "hot code" in puzzle 2.)
The analogy
Zygote is a show house, fully furnished at boot. Each new app house is a copy of it, but the furniture isn't duplicated: every house uses the show house's furniture until it repaints a chair. Only then does it get its own copy of that chair.
Check yourself
Sources
What you now know
Cold start = fork Zygote, create your Application, create your first Activity. Anything slow in Application.onCreate() is paid on every cold start, before the user sees anything.
Answer every question above correctly to unlock the next puzzle.