skip to content

Your runtime always finishes a trace by sweeping, yet its batch jobs range from 2% to 80% survivors — how would you decide whether to pick the finishing move per cycle?

level: principalimportance: should knowfreq 36%

answer

  1. the range is not the distribution
  2. the reserve is funded every cycle
  3. the choice precedes the measurement
  4. phase changes break the obvious predictor
  5. separating workloads beats a dual-path collector

basics

~20 s

Decide on evidence, not on the range: the copy path only pays where the survivor share is genuinely low, and it must be funded with reserved space in every cycle, including the ones that sweep. Measure the survivor share per cycle, cost both finishes on real traces, and prefer separating workloads over a collector with two paths.

solid answer

~50 s

Treat it as a funding decision, not a tuning one. The survivor share is already known when a trace ends, so choosing per cycle is mechanically possible — but the choice must be made **before** the finish, from a prediction, usually the previous cycle's share, and that predictor is worst exactly at a phase change. The copy path also costs something in every cycle: capacity able to hold every survivor has to be reserved permanently, whether or not that cycle uses it. So I would measure the distribution of survivor shares per job, cost both finishes over recorded traces, and adopt adaptivity only if the distribution is genuinely bimodal, the reserve is affordable, and the mispredicted case is survivable. Where jobs are separable, running the low-survivor ones under a different configuration is cheaper than maintaining two finishing paths.

go deeper

for a junior

The takeaway is that a collector's cheapest finish depends on how much survives, and that keeping the option of a second strategy costs memory even on the cycles that do not use it.

for a middle

Be able to explain why the choice has to be predicted rather than measured: the destination capacity must already exist before the finish runs, so the space commitment precedes the evidence.

for a senior

Show the measurement plan — survivor-share distribution per job, both finishes replayed over recorded cycles, predictor error concentrated around phase changes — rather than reasoning from the algorithms alone.

for a principal

Weigh a permanent fleet-wide reserve and a second code path in the component where bugs are silent corruption against the simpler move of separating the workloads, and say what evidence would reverse your call.

## What "adaptive" would actually commit you to The proposal sounds like a switch, but it is three commitments: - **Two finishing implementations in one collector**, each correct on its own and correct in whatever order they alternate — including the case where a sweep-finished heap with holes is the input to a copying finish, and the reverse. - **A permanent space reserve**, because the copy path must be able to place every survivor somewhere else in the worst case. That capacity is funded in every cycle, including the many that end with a sweep. - **A prediction**, because the finish is chosen before it runs. The survivor share is exact only once the trace has completed, and even then the decision must be made for *this* cycle from evidence about earlier ones. The spread from 2% to 80% is an argument that one fixed answer is wrong for someone. It is not yet an argument that the collector should decide. ## What I would measure first 1. **The distribution of survivor shares per job and per cycle**, not the range. A range of 2–80% is consistent with a bimodal population, where adaptivity has something to choose between, and equally with a smooth spread clustered in the middle, where it almost never chooses the copy path. 2. **Both finishes costed over the same recorded cycles.** Replay the observed survivor shares against a cost model with real constants — bytes copied and references rewritten for one, blocks visited for the other — instead of arguing from asymptotics. The sweep's per-block constant is small, so the crossover sits lower than intuition suggests. 3. **The predictor's error rate.** Score "previous cycle's share" against the actual share, and look specifically at the cycles around a phase change — the start of a new stage in a job, a cache being filled, a large structure being retained — because that is where a wrong choice is both likely and expensive. 4. **What the reserve displaces.** Memory held back for the destination is memory the program is not allocating in, which makes cycles more frequent for every job, including the ones that never use the copy path. ## Reading the answer off the evidence | what the measurement shows | reasonable conclusion | | --- | --- | | shares cluster low, and the reserve is affordable | adopt the copy path as the default finish; no adaptivity needed | | shares cluster high | keep sweeping; the copy path would be funded and never earn it | | genuinely bimodal, and the two modes track identifiable jobs | separate the jobs by configuration rather than making the collector decide | | genuinely bimodal within one job, predictor accurate | adaptivity is justified — this is the only case that actually argues for it | ## Cheaper alternatives to weigh against it - **Separate the workloads.** If the low-survivor jobs are identifiable, running them under a configuration that always copies gets most of the benefit with none of the prediction risk or the dual-path complexity. - **Keep one finish and add a rare fallback.** A collector that normally sweeps and compacts only when the surviving layout has become the problem is two paths as well, but the second runs rarely and is triggered by an observed condition rather than a forecast. - **Change the input instead of the finish.** If a job's survivor share is high because it retains what it does not need, the cheaper fix is in the job, and no collector policy recovers that. ## How I would defend the decision - State the cost that does not go away: the reserve is paid in every cycle, so the copy path must earn its keep across the whole distribution, not in its best cases. - Put a number on the crossover from the replay rather than asserting where it lies. - Name the failure mode explicitly — a mispredicted phase change choosing the copy path on a cycle where most of the heap survives — and say what it costs when it happens, since it will. - Prefer the reversible step: a per-job configuration can be rolled back for one job; a second finishing path inside the collector is carried by everything the runtime runs, forever, and every future change has to be correct in both. ## What makes this a judgment call rather than a calculation There is no survivor share at which the answer is forced. The same measurements support "adopt copying everywhere", "keep sweeping and separate the outliers" and "make it adaptive", and which one is right depends on how much memory the platform can reserve, how stable the jobs are, and how much complexity the team can carry in a component where a bug is silent memory corruption rather than a failed request. A good answer commits to one, says what evidence would overturn it, and says what it would cost to reverse.

  • Why not just read the survivor share at the end of the trace and choose then?
    You can read it then, but the reserve for the copy path has to have been funded long before — capacity able to hold the survivors cannot be conjured at the end of a trace. So the space decision is always made in advance, and only the cheap part of the choice is available late. That asymmetry is what makes this a funding question rather than a scheduling one.
  • What would convince you to reject adaptivity outright?
    A unimodal distribution, or a reserve the platform cannot afford, or a predictor whose errors concentrate exactly on the expensive cycles. Any one of those means the second path is carried by every job in the fleet and earns its cost for almost none of them, while adding a component whose bugs corrupt memory silently.
  • How would you stage the change if you did adopt it?
    Start by costing both finishes offline from recorded cycles so nothing in production changes. Then run the copy path as a fixed configuration on the jobs the data says would benefit, which is reversible per job. Only if that shows the benefit is real, and varies within a single job rather than between jobs, does a per-cycle choice inside the collector become worth building.

saying these in an interview costs you the question

  • Treats a wide range of survivor shares as proof adaptivity is needed
  • Forgets the reserve is funded in cycles that never copy
  • Assumes the current cycle's survivor share is known before choosing
  • Proposes two finishing paths without costing the complexity
  • Argues from asymptotics without measuring the per-block constants