Zombie and orphan processes — what happens when parent or child disappears
Every process has a parent — the one that created it — and the operating system has specific, well-defined rules for what happens to that relationship when either side ends first. Two of the resulting states have genuinely unsettling names for a reason.
Beginner
3 min read
The parent-child relationship processes always have
Every process (except the very first one, from the boot process lesson) is
created by another process — its parent. A shell starting a program, a
web server forking a worker, or your own code calling fork() (from the
copy-on-write lesson) all create this same relationship, and the operating
system has specific rules for what happens when one side of that
relationship ends before the other does.
Zombie: a child that finished, but nobody collected the result
When a child process finishes, it doesn't disappear from the system
instantly — it becomes a zombie, keeping just enough information around
(its exit code, mainly) for the parent to retrieve with a wait() system
call. A zombie isn't running, isn't using CPU or real memory, and isn't
technically "stuck" — it's simply waiting for its parent to formally
acknowledge that it finished and read its exit code.
A zombie only becomes a real problem when the parent never calls
wait() — a bug, not a normal condition — leaving zombies to accumulate
indefinitely. Each one uses a negligible amount of memory (just a process
table entry), but enough accumulated zombies can eventually exhaust a
system's maximum process count, itself a genuine, if unusual, cause of "why
can't this server start any new processes at all."
Orphan: a child whose parent disappeared first
The opposite situation — a parent process ending before its child does —
produces an orphan. Rather than being left with no parent at all
(which would leave nobody able to ever call wait() on it once it
finishes), the kernel automatically re-parents the orphan to the system's
init process (PID 1, from the boot process lesson), whose job specifically
includes calling wait() on any orphan that finishes, cleaning it up
properly.
This re-parenting is exactly what prevents orphaned processes from becoming
permanent zombies themselves — init exists specifically to make sure
someone is always available to clean up after any process whose original
parent is gone.
Why this matters day to day
ps aux showing a process in state Z (zombie) is a genuine, specific
signal that a piece of code isn't calling wait() on its children properly
— worth investigating directly rather than assuming it's harmless just
because a single zombie uses almost no resources. Long-running services
that spawn child processes (a web server forking workers, a script
launching subprocesses) are exactly where this bug shows up in practice,
and it's a real, recurring category of process-management mistake distinct
from a process simply crashing or hanging.