AOSP Framework & Internals
3 min read

ActivityManagerService (AMS)

The undisputed brain of Android. Understand how the AMS orchestrates processes, lifecycles, and the dreaded OOM Killer.

The ActivityManagerService (AMS) is the most critical and complex service running inside the Android System Server. Do not let the name fool you: it manages much more than just Activities. It manages the lifecycle of the entire operating system.

It is a massive Java class (often exceeding 30,000 lines of code) responsible for managing Activities, Services, BroadcastReceivers, and ContentProviders across every single app installed on the device.

The Process Lifecycle and oom_adj

The Linux Kernel does not understand what an "Android App" is. It only understands processes and memory. If the device runs out of RAM, the Linux Out-Of-Memory (OOM) killer will blindly terminate processes to free up space.

To prevent the kernel from killing the music player you are currently listening to, the AMS explicitly manages process priorities using oom_adj scores.

  • Foreground App: Has an oom_adj score of 0. The kernel will never kill this unless the system is literally crashing.
  • Visible App: Has a score around 1 or 2 (e.g., an app visible behind a transparent dialog).
  • Service Process: Has a score around 5 (e.g., background cloud sync).
  • Cached/Empty Process: Has a high score like 9 to 15. These are apps you pressed the Home button on hours ago.

When the system needs RAM, the kernel's LMK (Low Memory Killer) starts killing processes with the highest oom_adj score first. The AMS dynamically recalculates these scores hundreds of times a second and writes them into the Linux kernel via /proc/[pid]/oom_score_adj.

# Platform developers can monitor exactly how the AMS is ranking app priorities
adb shell dumpsys activity oom

The Activity Launch Flow

When you click an app icon on your launcher, a massive sequence of IPC calls begins.

  1. The Intent: The Launcher calls startActivity(), sending an Intent to the AMS via Binder IPC.
  2. Resolution: AMS asks the PackageManagerService to resolve the Intent and find the target app.
  3. Process Check: AMS checks if the target app's Linux process is already running.
  4. Zygote Fork: If the process is dead, AMS opens a local socket to the Zygote and commands it to fork() a new Dalvik/ART process for the app.
  5. Application Thread Binding: The newly spawned app process starts up and immediately calls back into the AMS, passing its IApplicationThread Binder token.
  6. Lifecycle Dispatch: AMS finally uses that Binder token to tell the app, "Execute onCreate() and onResume()."

Sub-Services

Because the AMS grew too large, Google recently refactored it. While AMS is still the main entry point, actual component management has been split into internal sub-services like ActivityTaskManagerService (ATMS) which exclusively handles the UI stack.