GC

Concepts

  • Garbage Collection is the process of freeing heap space for allocation of new objects.
    • Marking identifies live (reachable) objects and marks them as still used, leaving the others to be considered garbage.
    • Sweeping traverses the heap to find the free space between live objects, recording it in a free list for future allocation.
    • Compaction defragments the heap to increase the amount of contiguous free space, speeding up future allocations.
  • Generations are separate memory pools holding objects of different ages.

GC generations

The weak generational hypothesis states that:

Most objects only survive for a short period of time.

Thus the JVM splits heap space allocations into a number of generations:

  • Young:
    • Eden is where most new objects are allocated.
    • 2x Survivor spaces, one of which is empty at any given time, serving as the destination for any live objects in eden and the other survivor space during GC. After a GC, eden and the source survivor space are both empty. Objects remain in the survivor space until after a number of copies between survivor spaces or until there isn't sufficient memory to keep them there, after which they are copied into the old region in a process known as ageing.
  • Old stores aged or long-lived objects.

Objects are allocated in the young generations. GC occurs in each generation when the generation fills up. GCs in young generations are considered "minor", and most objects are collected here.

As surviving objects age, they're moved to the old generation. GCs in older generations ("major" collections) result in the entire heap being collected, and typically take much longer.

Collectors

The JVM supports a number of different GC implementations. Generally it is wise to allow the JVM to choose the best implementation for the application, and attempt to adjust heap and generation sizes before switching collectors. Use a concurrent collector to reduce pause time, and a parallel collector to increase throughput on multi-core systems.

Troubleshooting

  • -XX:+PrintFlagsRanges prints the range of all the flags.z
  • -XX:+PrintCommandLineFlags prints "ergonomically selected" default JVM flags.
  • -XX:+PrintFlagsFinal prints the final/resolved set of flags the JVM will run with, including defaults.
  • -XX:+PrintGCDetails
  • -XX:+PrintAdaptiveSizePolicy prints information about adaptive generation sizing.
  • -verbose:gc or -Xlog:gc* enables logging of GC events.
    • -Xlog:gc+heap=info prints G1 regions consumed by humongous objects.
    • -Xlog:codecache=trace prints code heap status.
  • -XX:+HeapDumpOnOutOfMemoryError dumps heap to a file on OOM.
    • -XX:HeapDumpPath=path specifies the path to the dump file.
  • -XX:+DisableExplicitGC disables explicit GC via System.gc().
  • If more than 98% of the total run-time is spent in GC and less than 2% of the heap is recovered, this collector throws an OutOfMemoryError to prevent applications from running for extended periods of time while making little or no progress because of an undersized heap. This behaviour can be disabled with -XX:-UseGCOverheadLimit.

Goals

The JVM attempts to address the following goals, in descending order of priority:

  • Maximum pause-time goal, set with -XX:MaxGCPauseMillis=n.
  • Throughput goal, set with -XX:GCTimeRatio=n as a ratio of time spent in GC to time spent in application code (1/(n+1)1 / (n + 1); e.g. the default value of 99 sets a goal of 1/1001 / 100, or 1%).
  • Implicitly, minimising the size of the heap.

Understanding GC events

[Full GC (<trigger>)  (<start size>-><finish size>(<delta>), <real time>]

Tuning

  • -Xnoclassgc disables garbage collection of class objects.
  • -XX:+AggressiveHeap enables aggressive heap optimisation, for long-running applications with intensive memory allocations.
  • -XX:+ShrinkHeapInSteps toggles incremental reductions of the heap toward the target size instead of multiple GC cycles.
  • -XX:InitialSurvivorRatio configures the initial eden:survivor space ratio used by the collector.
  • -XX:+UseAdaptiveSizePolicy toggles adaptive sizing of the survivor space ratio.
    • -XX:SurvivorRatio configures the constant eden:survivor space ratio used by the collector when -XX:-UseAdaptiveSizePolicy is specified.
  • -XX:TargetSurvivorRatio sets the desired percentage of survivor space used after a young GC (defaults to 50%).
  • -XX:MaxTenuringThreshold sets the maximum tenuring (ageing) threshold for use in adaptive GC sizing.

References


Children
  1. G1
  2. Parallel
  3. Serial
  4. ZGC

Backlinks