A mobile navigation back-stack is a LIFO (last-in, first-out) structure: push(screen) and pop() are both O(1). Under real device memory pressure, the OS cannot keep every backgrounded screen fully alive — it evicts the ones furthest from the visible top first, once the total resident memory of the stack exceeds a budget:
while Σ live[i].weight > budget:
evict = argmax( distance_from_top(i) ) over live, non-top i
live[evict] = false; mem[evict] ≈ 0 (only a small saved-state bundle remains)
The top (foreground) screen is never evicted — it's what the user is looking at. When you go Back into a screen that was evicted, the OS must recreate it from its saved-state bundle before it can be shown again — this is the same cost Android pays in onCreate()/onRestoreInstanceState() and iOS pays reconstructing a popped view controller:
recreationCost(ms) = baseCost + weight(MB) × costPerMB
Push (singleTop) mirrors Android's launchMode="singleTop" / iOS "pop-to-existing": if the screen already sits on top of the stack, its state is simply refreshed instead of pushing a duplicate entry — this is exactly how a tapped notification avoids stacking the same screen twice. Clear to root mirrors FLAG_ACTIVITY_CLEAR_TOP / popToRootViewController, collapsing the whole stack back to the entry screen in one step.
Heavier screens (Media > Detail > List > Form) are evicted — and become expensive to recreate — sooner, which is why real apps keep list/detail screens cheap and lazily reload heavy media instead of holding it all in memory.
This 2D view draws the same stack as a staircase of cards receding up-and-right instead of a 3D scene — drag to pan and scroll to zoom around it exactly as you would orbit the 3D version.