Android from the foundation · Puzzle 10 of 16

Zygote, the process every app starts from

Starting ART and reading Android's own code into memory takes seconds. Android does it once, when the phone starts, and makes every app a copy of that.

The problem

In puzzle 8, ART lived inside every app's process. But every app also uses Android's own code, thousands of classes like Activity. Starting ART and reading all of that code from files into memory takes seconds. If every app did it from scratch at every tap on an icon, opening apps would be slow.

See it

At boot Zygote loads ART and the framework; opening an app forks Zygote, and the copy becomes the app; Zygote also forked system_server kernel ARTframework ARTframework ARTframeworkZygote fork your app+ your codeUID system_server
  1. When the phone starts up, at boot, Android starts one process, Zygote. It starts ART and loads (reads into its memory) the framework, Android's own code that every app uses. Then it waits.

    Step 1 of 4
  2. You open an app. system_server asks Zygote for a new process, and Zygote asks the kernel to fork: make a new process that starts as a copy of Zygote. Predict: what's already loaded in the copy?

    Step 2 of 4
  3. Everything: ART and the framework. The copy switches to your app's UID (only Zygote's copies may do this, once, before any app code runs) and loads your app's code (its DEX, plus any code translated ahead of time). No waiting.

    Step 3 of 4
  4. Zygote did the same at boot for system_server: the town hall started as a copy too.

    Step 4 of 4

The building block

The phone starting up is called boot. Android's own code that every app uses, like the Activity class that every screen is built from, is called the framework.

At boot, Android starts one process, Zygote, which starts ART, loads the framework (reads its code from files into the process's memory), and then waits. When you open an app, system_server asks Zygote for a new process, and Zygote asks the kernel to fork: to make a new process that starts as a copy of Zygote. The copy already has ART and the framework loaded. It switches to the app's UID (only Zygote's fresh copies may do this, once, before any app code runs) and loads the app's own code (its DEX, plus any code already translated ahead of time). Zygote also forked system_server at boot, so the town hall starts fast too.

Android's code is public. In it, 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 ↗ (main() is where a program starts running) does exactly this: load, start system_server, then wait for "start an app" requests.

The analogy

Zygote is a show house, furnished at boot. Every new house on the street is built as a copy of it, already furnished, then given its own key.

Check yourself

You open three apps. How many times does Android load the framework from scratch?

Not quite. Every app uses Android's own code, like the Activity class. Zygote loads it once.

Not quite. Each app is a copy of Zygote, which already has the framework loaded.

Right. Zygote loads it once; every app process starts as a copy.

After the fork, how does the new process become your app and not Zygote?

Not quite. The copy changes right away: new key, your code.

Right. Fork copies, then the copy becomes your app.

What's the difference between Zygote and system_server?

Not quite. Both start at boot, but Zygote only starts processes, and system_server makes the decisions.

Right. Different jobs: copying versus deciding.

Sources

What you now know

Zygote starts with the phone, with ART and the framework loaded. Every app's process begins as a copy of it, a fork, so apps start fast.