Middle · Design · Retaining paths, cycles and dominators

How would you prove that deleting one cache entry releases the intended object graph?

Think through your answer before opening the explanation.

Memory & GC

Reveal answer and reasoning

Choose one ownership change at a time. Remove an event subscription, evict a specific cache entry, or complete a pending request, then rerun the same workload. Verify the expected application state and compare a later heap at a comparable boundary. If the payload stays live, find another path rather than adding forced collections until a graph seems to disappear. The second root might be a task continuation, a diagnostic local, an interop handle or a different cache.

For an interview, distinguish type counts, shallow bytes, retained bytes and resident memory. Explain why a disconnected cycle is eligible while a single small reachable owner can retain a large subgraph. Then discuss shared ownership: two roots to one array mean removing either alone is insufficient. A convincing answer specifies the edge to remove and the evidence that would confirm all unintended paths ended.

Add a third dictionary owner to the portable program and remove the first two. Predict both membership and identity results. Then replace one dictionary value with a fresh unrelated node and explain why the old cycle can still be held by the locals. Avoid claiming collection based only on dictionary Count.

In the weak-reference lab, remove the strong target owner while leaving the weak observer alive. Step through mark and reclaim, inspect the dotted edge, then reset. Compare that with the disconnected cycle. Write a short diagnostic plan for a twelve-byte cache entry retaining a one-megabyte buffer, including how you would avoid double counting when an active request also holds the same backing array.

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