In a HotSpot JVM with a generational heap, what are eden, the survivor spaces and the old generation, and what does each one hold?
answer
- heap = objects and arrays, shared by all threads
- young = eden + two equal survivors; one survivor always empty
- young GC copies survivors out, then frees eden wholesale
- survive enough collections => promoted to old
- region-based collectors: same roles, regions instead of contiguous blocks
basics
~20 sThe heap is shared by all threads and split into a young generation and an old generation. Young holds eden, where new objects are created, plus two survivor spaces holding objects that survived recent collections. Old holds objects that survived long enough to be promoted.
solid answer
~50 sThe heap is the thread-shared region where objects and arrays live, and a generational collector divides it in two. The **young generation** contains **eden**, where nearly every new object is created, and two **survivor spaces** of equal size, of which only one holds data at a time. A young collection copies the still-reachable objects out of eden and out of the occupied survivor into the other survivor, then declares the vacated spaces empty in one step. The **old generation** holds objects that have survived enough young collections to be promoted, plus anything too large or too pressured to stay young. Young collections are frequent and touch only the young generation; old-generation work is rarer and more expensive because the space is larger and its objects are typically long-lived. The proportions are configurable, and the boundaries may be logical rather than three contiguous blocks — region-based collectors label fixed-size regions with a role instead.
code
text · 7 lines|<---------------- Java heap ---------------->|
| young generation | old (tenured) |
| [ eden ][ S0 ][ S1 ] | |
^ new objects ^ one survivor is always EMPTY
young GC: live(eden + S0) --copy--> S1 (or --promote--> old)
eden and S0 freed wholesale; S0 and S1 swap rolesgo deeper
Name the spaces and their roles: eden for new objects, two survivors for recent survivors, old for long-lived ones.
Add the copying flow, the empty-survivor invariant, the role swap and why the design makes young collections cheap.
Note that the layout is logical for region-based collectors and connect the space proportions to promotion behaviour and observed collection cost.
Frame the split as an engineering trade — cheap frequent reclamation of a small space against expensive rare reclamation of a large one — and where that assumption stops paying off.
## The heap and its split The heap is the memory area where every Java object and array lives, shared by all threads of the process. A generational collector partitions it so that most collection work touches only a small, cheap part. **Young generation.** Divided into: - **Eden** — the allocation space. Essentially every new object starts here. - **Two survivor spaces**, conventionally *from* and *to*, of equal size. A crucial invariant: at any moment outside a collection, one survivor holds data and the other is empty. The empty one is the destination for the next collection. **Old generation** (also called tenured) — where objects go when they have survived enough young collections, or when they could not be accommodated in the young generation. Class metadata does *not* live here; it has its own area outside the heap. Neither do thread stacks or direct byte buffers. "On the heap" means objects and arrays, nothing else. ## What happens in a young collection A young collection is triggered when the allocation space cannot satisfy a request. It examines only the young generation: 1. Determine which objects in eden and in the occupied survivor are still reachable. 2. Copy each such object either into the empty survivor space or, if it is old enough or does not fit, into the old generation. 3. Declare eden and the previously occupied survivor entirely free — no per-object work for the garbage, because nothing dead was ever touched. 4. Swap the roles of the two survivors, so the one just filled becomes the source next time. Two consequences follow. First, the cost is proportional to what *survives*, not to how much garbage was produced: an application that allocates heavily but whose objects die immediately gets very cheap collections. Second, because live objects are copied rather than left in place, eden comes back both empty and unfragmented, so subsequent allocation is a simple advance of a pointer within the space. ## What the old generation is for An object that keeps surviving is copied from survivor to survivor, and each survival increments an age counter carried with the object. Past a threshold the collector stops copying it back and forth and *promotes* it into the old generation instead — the working assumption being that something which has already lived a while will likely keep living, so repeatedly copying it wastes work. The old generation is collected far less often. It is larger, its objects are mostly live, and reclaiming it therefore costs much more per collection, which is exactly why the design tries to prevent short-lived data from getting there. ## Sizes and shape Heap bounds are set with the standard minimum and maximum heap flags; the young/old split and the eden/survivor split have their own ratio flags, and modern collectors adjust them adaptively at runtime. The important thing for a mental model is proportion, not exact numbers: the young generation is typically a minority of the heap, and each survivor space is a small fraction of the young generation — far smaller than eden. That is why survivor capacity is a real constraint and why a burst of surviving data can overflow it. ## Layout is logical, not necessarily physical Older collectors implement these spaces as contiguous address ranges. Region-based collectors chop the heap into many fixed-size regions and give each region a role — eden, survivor or old — which can change from cycle to cycle. The generational *behaviour* described above is identical; only the address layout differs. So "the young generation" means "the set of regions currently labelled eden or survivor", not necessarily a single block of memory. A good answer states the roles and the copying flow, then notes that the physical arrangement depends on the collector. ## Reading the shape in practice When a GC log reports occupancy before and after a collection, those are whole-heap figures, so seeing them fall sharply on every young collection while the *post*-collection value slowly climbs is the normal signature of a healthy young generation feeding a slowly filling old generation.
- Why is a young-generation collection usually much cheaper than an old-generation one?It only inspects the young generation, which is small, and most objects there are already dead, so very little has to be traced and copied. Dead objects cost nothing because the whole space is reclaimed in one step rather than object by object. Old-generation collections cover a larger area whose objects are mostly still live, so far more work is required per collection.
- Does class metadata live in the young or old generation?Neither. Class metadata lives in its own native memory area outside the Java heap, sized by its own flags. Only objects and arrays occupy the generational heap. This distinction matters when diagnosing memory exhaustion, because a metadata problem and a heap problem have different causes and different flags.
saying these in an interview costs you the question
- Claiming both survivor spaces hold data at the same time
- Placing class metadata, thread stacks or direct buffers in the generational heap
- Believing collection cost scales with garbage produced rather than with surviving data
- Asserting the three spaces must be contiguous, which is untrue for region-based collectors
- Saying objects are always allocated in the old generation once the heap is large