Middle · Explain · Retaining paths, cycles and dominators

Why can a cycle be collectible while a tiny cache entry retains megabytes?

Think through your answer before opening the explanation.

Memory & GC

Reveal answer and reasoning

Shallow size describes the storage of an object itself, with the exact accounting depending on the tool and runtime. Retained size asks a graph question: how much would become unreachable if a particular ownership boundary were removed? Those quantities can differ dramatically. A small view can retain a large array. A large shared array can have multiple independent owners, so attributing all of its bytes independently to every owner overcounts memory.

A dominator lies on every path from a synthetic graph root to an object. If a cache entry dominates a payload, removing that entry's ownership can cut all those paths. If an active request also owns the payload, the cache no longer dominates it. An immediate dominator is a graph relationship, not necessarily a business object named Owner. Tools may use synthetic roots and groupings.

Read their definitions before treating a retained-size column as a sum of physical resident pages.

A weak reference offers optional access without establishing an ordinary strong retaining edge to its target. If TryGetTarget succeeds, the returned local reference is strong for its actual runtime-reported lifetime. That access can change the experiment: repeatedly polling a weak reference can keep acquiring a temporary strong target, and a debugger can introduce its own observations. A failed lookup should be handled as a normal state rather than as an exceptional corruption.

Do not use weak references to replace an explicit cache capacity policy indiscriminately. Collection timing depends on pressure and runtime decisions, so a weak cache has different hit-rate and lifetime behavior from a bounded strong cache. It is useful when recomputation is acceptable and optional presence is the intended contract. It is not a deterministic timer, an authorization store, or a way to make returned pooled memory safe after its lease ends.

What a strong answer covers

  • Tracing collection can reclaim disconnected cycles.
  • A dominator lies on every path from the synthetic root.
  • Shallow size is not the retained size of an ownership subtree.

Common pitfall

Calling every cycle a leak, or counting a shared backing array in full for each owner.

Follow-up questions

  1. How does a second independent root change retained-size attribution?
  2. What strong local does a successful TryGetTarget introduce?

Self-review

Choose what to revisit. These marks are your own assessment and are separate from lesson completion.

Primary references

Open lesson and code ↗

← All interview questions