skip to content

Inside a HotSpot young generation, how is space divided between eden and the two survivor spaces, what does the flag -XX:SurvivorRatio change, and what goes wrong when the survivor spaces are too small?

level: middleimportance: should knowfreq 45%

answer

  1. eden + S0 + S1, one survivor always empty
  2. SurvivorRatio=8 means each survivor is 1/10 of young
  3. copy eden + from-survivor into to-survivor, swap
  4. overflow promotes immediately regardless of age
  5. TargetSurvivorRatio 50% drives adaptive tenuring

basics

~20 s

The young generation is eden plus two equal survivor spaces; only one survivor holds data at a time. -XX:SurvivorRatio=N makes eden N times one survivor. If the surviving objects do not fit in the target survivor space, they are promoted to the old generation immediately, regardless of age.

solid answer

~50 s

A HotSpot young generation is eden plus survivor spaces S0 and S1 of equal size. Allocation happens in eden; one survivor is always empty and serves as the copy target. At a young collection, live objects from eden and from the occupied survivor are evacuated into the empty survivor, their age counter is incremented, and the roles of the two survivors swap. -XX:SurvivorRatio=N sets eden:one-survivor = N:1, so with the common default of 8 each survivor is one tenth of the young generation. If the target survivor cannot hold everything that survived, the overflow is promoted straight to the old generation - premature promotion - which fills old with objects that would have died shortly after. Oversized survivors are wasteful in the other direction: one survivor is always empty, so the space is doubly charged, and it is taken from eden, raising collection frequency. HotSpot's adaptive sizing normally tunes this itself against -XX:TargetSurvivorRatio.

code

text · 5 lines
text
-Xmn1000m -XX:SurvivorRatio=8
  eden = 800m, S0 = 100m, S1 = 100m   (one of S0/S1 always empty)

-Xmn1000m -XX:SurvivorRatio=4
  eden = 666m, S0 = 166m, S1 = 166m   (bigger survivors, smaller eden)

go deeper

for a junior

Recall the three spaces and that surviving objects are copied from eden into a survivor space rather than being left in place.

for a middle

State the ratio arithmetic exactly and explain survivor overflow leading to immediate promotion.

for a senior

Connect survivor sizing to the adaptive tenuring threshold and to old-generation growth under bursty load, and prefer measuring the tenuring distribution over guessing a ratio.

for a principal

Argue for leaving adaptive sizing on and fixing the allocation shape, reserving explicit ratios for workloads with a known, stable surviving-set profile.

## The three spaces The young generation is not one space but three: eden and two survivor spaces, conventionally called S0 and S1 or from-space and to-space. Objects are allocated in eden (each thread bump-allocates in its own buffer carved out of eden). The two survivor spaces are the same size and, by design, exactly one of them is empty at any moment outside of a collection. ## What a young collection does with them When eden fills, the collector traces from the roots and evacuates every reachable object out of eden and out of the currently occupied survivor space into the empty one. Each evacuated object's age counter, held in a few bits of the object header, is incremented. Objects whose age has reached the tenuring threshold, and any object that cannot fit in the target survivor, go to the old generation instead. Afterwards eden and the previously occupied survivor are entirely free, and the two survivors swap roles. The survivor spaces exist so an object can be given several chances to die before it is promoted. Without them every object alive at the first collection would land in the old generation, and the old generation would fill with short-lived garbage. ## The sizing flag -XX:SurvivorRatio=N sets the ratio of eden to a single survivor space. With SurvivorRatio=8 the young generation is divided into 8 + 1 + 1 = 10 parts: eden is 80% and each survivor 10%. Lowering the ratio to 6 gives each survivor 12.5%; raising it to 32 gives each about 3%. In HotSpot's parallel and serial collectors this is a direct sizing knob; under G1 the young generation is a set of regions and the eden/survivor split is chosen dynamically, though SurvivorRatio still acts as a target. ## Failure mode one: survivors too small If the surviving set of a collection exceeds the target survivor space, the excess is promoted directly to the old generation no matter how young it is. This is premature promotion. The symptoms are old-generation occupancy climbing steadily during normal traffic, frequent old or mixed collections, and eventually long full collections - even though the application's genuinely long-lived data is small. It is especially common under bursty load, where one unusually large batch of in-flight objects overflows a survivor sized for the average. A second, subtler effect: HotSpot tries to keep survivor occupancy at or below -XX:TargetSurvivorRatio (50% by default). When survivors run hot, the adaptive policy lowers the effective tenuring threshold, so objects are promoted after fewer collections, compounding the problem. ## Failure mode two: survivors too large Because one survivor is always empty, every megabyte given to survivor space costs two megabytes of young generation. Oversizing them shrinks eden, which raises minor-collection frequency, while half the reserved space sits permanently unused. Very large survivors also mean more data is copied back and forth between them, collection after collection, for objects that are going to be promoted eventually anyway - repeated copying of the same medium-lived objects is pure waste. ## Practical approach Measure before adjusting. With -XX:+PrintTenuringDistribution (or the equivalent unified-logging tag) you see the desired survivor size, the actual occupancy and the age histogram. If survivors are consistently overflowing, the first move is usually to enlarge the young generation as a whole rather than to re-slice it, because that reduces survivor volume at the source by giving objects more time to die. Re-slicing with SurvivorRatio is the right move when eden is already generous and the surviving set is simply larger than the default 10% slice. On modern collectors, leaving adaptive sizing enabled and fixing allocation behaviour usually beats hand-picking a ratio.

  • Why does HotSpot keep one survivor space permanently empty instead of using both?
    Because young collection is a copying collection: it needs a contiguous, empty destination to evacuate live objects into, which also compacts them and eliminates fragmentation in the young generation. The empty space is the to-space; after the copy the source spaces are freed wholesale and the roles swap.
  • Survivor overflow is reported in your GC logs. Do you raise -XX:SurvivorRatio or lower it?
    Lower it. The ratio is eden to one survivor, so a smaller number means proportionally larger survivor spaces. But first consider enlarging the whole young generation instead - that reduces the surviving volume itself by letting more objects die between collections, whereas re-slicing only makes room for the same survivors at the cost of eden.

saying these in an interview costs you the question

  • Thinking both survivor spaces hold data at the same time
  • Believing -XX:SurvivorRatio compares survivor to the whole young generation rather than eden to one survivor
  • Assuming objects are only ever promoted when they reach the tenuring threshold
  • Raising SurvivorRatio to get bigger survivors (it does the opposite)
  • Treating survivor space as free capacity, forgetting one copy is always idle

context