PrepZone Logo
PrepZone

JVM Memory Regions

Eden, survivor spaces, old generation and metaspace — the layout behind every tuning flag.

Why this matters

  • The generational layout is why garbage collection is fast at all, and it rests on one empirical observation about how objects behave.
  • OutOfMemoryError has several variants naming different regions, and the region tells you what kind of problem you have.
  • Tuning flags are meaningless until you know which space each one resizes.

The regions

Heap — shared by all threads
Young generation
EdenFresh objects
Survivor 0Survived once
Survivor 1Copy target
Old generationPromoted, long-lived objects
Outside the heap
MetaspaceClass metadata — native memory
Thread stacksOne per thread
Code cacheJIT-compiled methods
New objects start in Eden. Survivors are copied between the survivor spaces, and only long-lived objects are promoted to the old generation.
  • Young generation — where every new object is allocated. Subdivided into Eden and two survivor spaces.
  • Old generation, also called tenured — objects that have survived several young collections.
  • Metaspace — class metadata: field and method definitions, bytecode, the runtime constant pool. Native memory, outside the heap.
  • Code cache — native code produced by the JIT compiler.
  • Thread stacks — one per thread, holding frames. Native memory, not heap.

The weak generational hypothesis

The entire design rests on one observation that holds for almost all programs:

That is why a minor collection of a 500 MB young generation can take a few milliseconds: if only 2% of it survives, there are only 10 MB of objects to copy.

Eden and the survivor spaces

Java
Young generation
┌──────────────────────────┬────────┬────────┐
│          Eden            │   S0   │   S1   │
└──────────────────────────┴────────┴────────┘
     new objects here      one in use, one empty

The cycle

  • All allocation happens in Eden, by bumping a pointer — about as cheap as a stack push.
  • When Eden fills, a minor collection runs. Live objects are copied into the empty survivor space; Eden is then wholly empty.
  • Objects already in a survivor space are copied to the other one, and their age counter increments.
  • One survivor space is always empty, which is what makes the copy possible without extra space.
  • An object whose age passes the tenuring threshold is promoted to the old generation.

An object is also promoted immediately if it is too large for Eden, or if the target survivor space fills up.

Java
void process() {
    for (int i = 0; i < 1_000_000; i++) {
        String temp = "item-" + i;        // allocated in Eden, dead by the next iteration
        use(temp);
    }
}

A million strings, almost all collected by cheap minor collections. Nothing reaches the old generation.

Minor and major collections

AspectMinor (young) collectionMajor (old) collection
RegionEden and survivor spacesOld generation, often the whole heap
FrequencyOften — many times a minuteRarely
DurationMillisecondsTens of milliseconds to seconds
AlgorithmCopying — cost scales with survivorsMark-sweep-compact or concurrent marking
PauseShort stop-the-worldLonger, or mostly concurrent on modern collectors
Triggered byEden filling upOld generation occupancy crossing a threshold
  • Region

    Minor (young) collectionEden and survivor spaces
    Major (old) collectionOld generation, often the whole heap
  • Frequency

    Minor (young) collectionOften — many times a minute
    Major (old) collectionRarely
  • Duration

    Minor (young) collectionMilliseconds
    Major (old) collectionTens of milliseconds to seconds
  • Algorithm

    Minor (young) collectionCopying — cost scales with survivors
    Major (old) collectionMark-sweep-compact or concurrent marking
  • Pause

    Minor (young) collectionShort stop-the-world
    Major (old) collectionLonger, or mostly concurrent on modern collectors
  • Triggered by

    Minor (young) collectionEden filling up
    Major (old) collectionOld generation occupancy crossing a threshold

Frequent cheap collections plus rare expensive ones is the whole bargain.

Metaspace

Class metadata lives in native memory, sized on demand rather than fixed.

Java
// Metaspace holds, per class: the name, field and method definitions,
// bytecode, the constant pool, and the vtable for dynamic dispatch.

Before Java 8 this was PermGen, a fixed-size region inside the heap. Overflowing it was a familiar failure when redeploying an application server repeatedly, because each redeploy loaded a fresh copy of every class and the old ones were not always collectible.

What changed in Java 8

  • PermGen was removed and replaced by metaspace in native memory.
  • Metaspace grows automatically, so OutOfMemoryError: PermGen space largely disappeared.
  • Interned strings and static fields moved to the heap, where they can be collected normally.
  • A runaway metaspace is still possible — set -XX:MaxMetaspaceSize to cap it, so a class-loader leak fails fast instead of consuming all system memory.

The flags worth knowing

Java
# Heap size — set both to the same value in production to avoid resize pauses
-Xms2g -Xmx2g

# Young generation share of the heap
-XX:NewRatio=2          # old : young = 2 : 1, so young is one third
-Xmn512m                # or set the young size directly

# Eden : survivor ratio
-XX:SurvivorRatio=8     # Eden : each survivor = 8 : 1

# Per-thread stack size
-Xss512k

# Cap metaspace so a class-loader leak fails fast
-XX:MaxMetaspaceSize=256m

# Produce a heap dump automatically when the heap is exhausted
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/log/app

# Observe what is actually happening
-Xlog:gc*:file=gc.log:time,uptime,level,tags

Observing the regions

Java
# A live summary, updated every second
jstat -gcutil <pid> 1000

#  S0     S1     E      O      M     CCS    YGC   YGCT    FGC   FGCT
#  0.00  48.19  72.31  31.04  94.21  91.88   142   0.891     2   0.214

The columns are survivor 0 and 1, Eden, old, metaspace and compressed class space as percentages, then young collection count and total time, then full collection count and total time.

Reading it

  • Eden rising and resetting repeatedly is normal — that is minor collection working.
  • Old generation climbing steadily and never falling after major collections is the signature of a leak.
  • A high FGC count means full collections are frequent, which usually means the old generation is too small or something is being promoted that should not be.
  • Metaspace near 100% points at class loading, not at your objects.

Common misreadings

  • "The heap is split by object type." It is split by age. A String and a Connection both start in Eden.
  • "Objects are allocated in the old generation if they are large." Only if they are too large for Eden. Size is not the usual criterion; survival is.
  • "Metaspace is part of the heap." It is native memory. -Xmx does not bound it.
  • "PermGen still exists." It was removed in Java 8.
  • "Both survivor spaces hold objects." One is always empty; that is what makes copying collection possible.
  • "A major collection collects the young generation too." A full collection does. "Major" conventionally refers to the old generation, and the terms are used loosely enough that it is worth being explicit.

Quick recall

Everything you need if you only revisit this box.

  • The heap is generational: young (Eden + two survivors) and old. Division is by age, not type.
  • The weak generational hypothesis — most objects die young — is why a minor collection is cheap: cost scales with survivors, not garbage.
  • Allocation happens in Eden via a thread-local allocation buffer, so it is a pointer bump with no locking.
  • One survivor space is always empty. Surviving objects are copied across and age; past the tenuring threshold they are promoted.
  • Minor collections are frequent and short; major ones are rare and longer.
  • Metaspace holds class metadata in native memory and replaced PermGen in Java 8. Its exhaustion means a class-loader leak.
  • Always set -XX:+HeapDumpOnOutOfMemoryError and GC logging. Use jstat -gcutil to watch the regions.
  • A steadily rising old generation that never drops after a full collection is the signature of a leak.

Test yourself

Answer these before moving on — recall is what makes it stick.