skip to content

When would you let a reference strength cleared only under memory pressure size a cache, instead of an explicit bound?

level: principalimportance: should knowfreq 32%

answer

  1. free eviction is never free
  2. you are delegating the policy
  3. the collector knows only heap pressure
  4. grows to fill headroom, clears at peak
  5. a stated bound is reviewable

basics

~20 s

Rarely, and only for values that are cheap to rebuild and genuinely hard to size. The strength delegates eviction to a collector that knows heap pressure but nothing about hit rate, entry cost or fairness, so a fleet service should state a bound instead.

solid answer

~50 s

This strength keeps entries alive until the heap gets tight, then lets the collector clear them. What you are delegating is the **eviction policy**, to a component whose only input is memory pressure. It does not know which entries are hot, which cost a second to rebuild, or which tenant they belong to, and it tends to clear in a burst at exactly the moment the service is busiest — a cache-wide miss storm layered on top of a memory problem. The cache also grows into all available headroom, and every live entry is traced on every cycle, so it buys footprint and pause time as well. It is defensible for a single-process tool with recomputable values and wildly variable entry sizes, or as a second-chance tier beneath an explicit bound. For a fleet service the defensible answer is an explicit bound in entries or bytes, a measured hit rate, and a stated eviction policy.

go deeper

for a junior

Recall that this strength keeps entries only while there is spare memory, so it is a hint to the collector and never a guarantee that a cached value will still be there.

for a middle

Explain what is being delegated: eviction order decided by heap pressure alone, with no knowledge of hit rate, entry cost or size, and clearing that is coarse rather than gradual.

for a senior

Show the production consequence — a cache that expands into all headroom, raises tracing cost every cycle, and empties in a burst during peak load, producing a rebuild stampede.

for a principal

Take a position: a cache with no owned bound has no capacity story, so mandate an explicit bound with a measured hit rate and allow the pressure-cleared strength only as an opportunistic tier beneath it.

## What you are actually delegating A reference strength cleared only under memory pressure occupies the rung between strong and weak: the collector keeps the target while there is room and clears it when there is not. Used for a cache, it looks like getting eviction for free. What it really does is hand the **eviction policy** — the single most consequential design decision in any cache — to a component that was built to answer a different question. A cache policy needs to know which entries are hot, how expensive each is to rebuild, how large each is, and whether one tenant is crowding out another. A collector knows one thing: how full the heap is. Those are not the same input, and no amount of tuning makes one into the other. ## What the collector knows, against what a policy needs | the policy needs | the collector has | |---|---| | recency or frequency of use | nothing; reachability is not use | | cost to rebuild an entry | nothing | | a target hit rate | nothing | | fairness across tenants or keys | nothing | | a capacity number to size against | only free heap, which changes constantly | ## The costs that arrive later - **Footprint expands to fill headroom.** The cache has no reason to stop growing until pressure arrives, so the steady-state live set is 'as much as the heap allows'. Capacity planning against that number is impossible, because it *is* the limit. - **Tracing cost rises with it.** Every retained entry is a live object the collector walks. A cache sized by the collector makes the collector's own work larger, which is a feedback loop, not a neutral trade. - **Eviction is a cliff, not a curve.** Clearing happens when memory is tight, which correlates with peak load. The service takes a cache-wide miss storm and a rebuild stampede at the worst possible moment, and the rebuild traffic itself needs memory. - **No number to reason about.** You cannot answer 'how much memory does this cache use' or 'what is its hit rate at steady state' in a review, because both are emergent. - **Portability is poor.** Ecosystems differ sharply: some offer this strength, some do not, and those that do differ in how aggressively they clear. A design that depends on the clearing policy does not travel. ## Where it is genuinely defensible 1. **A single-process tool, not a fleet service.** A batch job or a developer tool where a miss costs milliseconds, nothing else shares the heap, and nobody will ever page on it. 2. **Values that are pure and cheap to rebuild**, where the worst case of a mass clear is extra CPU and never a correctness or latency-contract problem. 3. **Entry sizes that vary by orders of magnitude**, where a count-based bound is meaningless and a byte-based bound would need a size estimator you do not have. 4. **As a second-chance tier beneath an explicit bound** — entries evicted from a bounded cache demoted to pressure-cleared strength, so they survive if there is room. This keeps the capacity story intact and uses the strength as an opportunistic bonus, which is the only shape that scales to a fleet. ## How to decide, and what to measure 1. Establish the **cost of a miss**. If it is a recomputation on the same machine, the strength is arguable. If it is a network call, a lock, or a tail-latency budget, it is not. 2. Establish whether a **bound exists that you can state**. If someone can write down 'at most N entries' or 'at most M megabytes' and defend it, write that instead — a stated bound is reviewable and a delegated one is not. 3. Measure **hit rate against size** with a bounded cache first. It is usually flat above some knee, and the knee is the bound. Finding it removes the whole argument for delegating. 4. If you still delegate, **measure the clear events**: how often the collector clears, how much it clears at once, and what the miss storm does to latency at the moment it happens. If nobody is watching those, the design is undefended. ## The position to argue in an interview The strong answer says this is not really a memory question but an ownership question: a cache whose size nobody owns has no capacity story, and a service without a capacity story cannot be sized, alerted on, or run by anyone who did not write it. The strength has a narrow legitimate use as an opportunistic extra tier, and a very common illegitimate one as a substitute for deciding how big the cache should be.

  • Why does a cache sized by memory pressure make collection itself more expensive?
    Every retained entry is a live object the collector must trace each cycle, and a cache that grows until pressure arrives maximises exactly that set. Higher live-set size means longer marking work and less headroom per cycle, so the cache and the collector push against each other rather than one absorbing the other.
  • What does a pressure-cleared tier look like when it is used well?
    Underneath a cache with a stated bound. Entries evicted by the bound are demoted to the pressure-cleared strength rather than dropped, so they are reclaimed if the heap needs the room and serve a free hit if it does not. The capacity story stays owned by the explicit bound.
  • How would you tell from production data that such a cache is hurting a service?
    Look for clear events correlated with load rather than with idleness, followed by a miss-rate spike and a rebuild burst, and a live-set floor that tracks available heap instead of a working-set size. A latency histogram that grows a second mode right after each clear is the clearest evidence.

saying these in an interview costs you the question

  • Calls it free eviction with no policy consequences
  • Assumes the collector clears the least useful entries first
  • Believes such a cache needs no capacity number for planning
  • Ignores that retained entries are traced on every cycle
  • Expects clearing to happen while the service is idle
  • Treats the clearing behaviour as identical across ecosystems