No, it’s not about religion, or reality TV, or random rant.

Those are names in Java’s memory management model.

In the beginning, Java gc was simple and stupid: run when heap is full. So your app happily gobbles up memory until… a… lo…ng pau…se.

Then the Java guys found a common pattern among most apps: most objects die young (used only for a short time), but those who survive live long. The X unit of the graph is object life span not in time, but in terms of number of bytes allocated between their birth and death.

Therefore Java memory is now divided into 3 generations:

  1. Young
    1. eden
    2. two survivor spaces
  2. Tenured
  3. Permanent (and code cache): stores JVM’s own stuff

Heap = young + tenured. It starts at physical memory / 64, and max is min(mem/4, 1GB), unless you specify -Xms and -Xmx. Default perm size is 64MB (-XX:MaxPermSize). Default code cache is 32MB (-XX:ReservedCodeCacheSize).

Now object life cycle is like this:

  1. Objects are always allocated to eden.
  2. When eden fills up, a fast but not comprehensive gc (minor collection) is run over the young generation only.
  3. All survivors are moved into one survivor space, plus everything from the other survivor space (survivors from the previous minor collection).
  4. When objects in survivor space is old enough (or survivor fills up), they are moved to tenured.
  5. When tenured fills up, a major collection is run that is comprehensive: all heap, all objects.

Run java with -verbose:gc (or -Xloggc:file) and it prints stuff like this:


[GC 15081K->14088K(20988K), 0.0110810 secs]
[Full GC 15078K->13996K(20988K), 0.1845024 secs]

GC = minor collection and Full GC = major. Numbers are pre gc -> post gc (total committed heap).

Advertisements