This article is translated from Getting Started with G1 Gabage Collector. Not exactly translated. At the same time, according to the reference documents at the end of the article, some content is appropriately added

The following chapters omit Purpose, Time to Complete, Introduction, Hardware and Software Requirements, Prerequisites, Java Overview, and Java Runtime Edition, Java Programming Language, Java Development Kit, Java Virtual Machine, Reviewing Generational GC and CMS, CMS Collection Phases, Reviewing Garbage Collection Steps, Basic Command Line, Key Command Line Switches, Logging GC with The G1, the summary,

The Hotspot architecture

The Hotspot JVM architecture has very powerful features and capabilities that enable high performance and large scale scalability. For example, the Hotspot JVM’S JIT compiler optimizes dynamically. In other words, these optimizations generate high performance local machine instructions for the current system architecture while the Java application is running. In addition, with mature evolution and continuous engineering changes to the runtime environment and multi-threaded garbage collection, Hotspot JVM can remain highly scalable even on the largest existing computer systems

The main components of the JVM include class loading, runtime areas, and the execution engine

Hotspot Key Components

The key components for Hotspot to achieve high performance are shown below

The JVM’s performance gains are mainly due to three components. The heap is where objects are stored, and it is where the garbage collector chooses to manage them. In most cases, we just need to adjust the heap size and choose the right garbage collector. JIT compilers can also have a significant impact on performance, but adjustments are generally made in newer JVMS

Performance Basics

Generally speaking, when it comes to Java applications, you focus on two things: response and throughput

The response

A response describes how fast the system returns data, such as:

  • How fast does the desktop UI respond to an event?
  • How fast does the site return to a page?
  • How fast does the database return results?

For response-focused systems, long pauses are unacceptable

throughput

Throughput focuses on the tasks that maximize system processing over time and can be measured as follows:

  • Number of transactions completed in a period of time
  • The number of tasks a batch program can complete in an hour
  • The number of queries that the database can complete in an hour

Long pauses are acceptable for systems that are focused on throughput (focusing on a period of time, so fast responses are not a consideration)

G1 garbage collector

G1 (garbage-First) is a server-side Garbage collector designed to handle multi-core, large-memory machines and achieve the target pause time as much as possible while maintaining high throughput. It has been fully supported since JDK 7 Update 4 and is designed to:

  • The CMS collector can execute concurrently with the application thread
  • Compact space eliminates lengthy GC pauses
  • GC pause times are predictable
  • Don’t want to sacrifice throughput
  • You don’t need a larger Java heap

G1 will serve as a long-term replacement for CMS, and there are some differences that make G1 a better choice than CMS.

  • The first is that G1 is a compressed collector. The compression of G1 makes it possible to completely avoid using a list of available Spaces that can be allocated at a fine granularity and instead use regions, which simplifies the collector and eliminates potential fragmentation problems.
  • Another is that G1 lets users set the pause time for a targeted collection

G1 Operation Overview

The older generation of garbage collectors divided the heap into three parts: young, old, and a permanent strip with a fixed memory size

All memory objects in one of these three areas are different in G1:

  • The heap is divided into equally large regions, and each Region has continuous virtual memory. Collections of some regions are allocated to Eden, Survivor, and Old just like old collectors, but these three regions have no fixed size, which makes memory usage more flexible

  • Regions labeled E (small squares in the figure) represent Eden space, S represents survivor space, O represents tenured space, and gray is the unused region of the heap.

When garbage collection is executed, G1 performs concurrent global marking first and then knows which regions are basically empty after garbage collection. The same goes for compression, where G1 uses a pause prediction model to reach the expected pause times used for the definition, and then selects several regions to recycle based on the target time.

Regions selected as garbageable are collected through evacuation, where G1 copies objects from multiple regions to a Region in the heap, freeing memory by squeezing one half on each side. Evacuation is performed in parallel in multiple cores to reduce pause times and increase throughput. By doing this, G1 reduces debris during each garbage collection while still staying within the user-defined pause time that other garbage collectors cannot.

G1 is not a real-time collector; it will try to reach the defined pause times as much as possible, but not necessarily. Based on the last collection, G1 is able to predict how much of the area can be recycled within a user-defined period of time (using this data, it is also possible to make predictive models that can be applied to the collection process)

Note that G1 has both concurrent (execution with application threads, such as thinning, marking, and cleaning) and parallel (multithreading, such as Stop the Word) phases. The full GC is still single-threaded and should be avoided by applications if possible

G1 footprints

If you migrate from ParallelOldGC or CMS to G1, it is likely that more process space will be used. This is most likely related to Remembered Sets and Collection Sets:

  • Remembered Sets: Also known as RSets. This is used to record references to regions. Each Region has an RSet that makes it possible to reclaim each Region independently and in parallel. The effect of the size of the entire RSet is less than 5%
  • Collection Sets: Also known as CSets, used to record regions that can be reclaimed. During GC, all living objects in CSets are evacuated (copied or deleted), and regions in CSets can be Eden, survivor, and Old. The total CSet impact on JVM space is less than 1%

Tips for using G1

G1 is a garbage collector designed to handle large amounts of memory with priority GC latency. In other words, the heap size should be greater than or equal to 6G and the pause time should be less than 0.5 seconds. If the old GC shows the following characteristics, migration can be considered:

  1. Full GC takes too long or too often
  2. Object assignment or promotion rates vary significantly
  3. Don’t want long GC or compression pauses (beyond a certain threshold, such as 0.5 seconds)

Look at the G1 Young Gc step by step

  1. G1 heap structure. The heap is divided into multiple regions of fixed size

  • The size of regions is determined when the JVM is started. Typically, there are 2000 regions and each Region ranges in size from 1 to 32 MB
  1. G1 heap allocation. A Region is logically mapped to Eden, survivor, and Old

  • Regions of the same color represent the same role, and live objects are evacuated (copied or deleted) from one Region to another.

In fact, in addition to Eden, Survivor, and Old as shown in the figure above, there is another type: Humongous Regions, which are designed to store objects that are more than 50% of the size of a single Region and use contiguous regions if the size is greater than one Region.

  1. The young generation in G1

The blue Region identifies the old generation object, and the green Region identifies the young generation object

  • Gray indicates unused memory space
  • The light green is the young generation
  • The light blue is the old generation
  • Dark green indicates recently copied into the young generation (not shown)
  • Dark blue indicates that it was recently copied to the older generation (not shown)

Note that these areas do not have to be contiguous like the old garbage collectors

  1. Young GC occurs in G1

Surviving objects are evacuated (copied or deleted) to one or more survivor regions, and if age thresholds are reached, some objects are promoted to tenured regions

  • The red circle in the figure indicates that the Young GC only scanned the young generation, and the arrow points to the place in step 5 where the surviving objects were evacuated (copied, deleted)

This is a stop the word (STW) pause, and the size of Eden and survivor is calculated for the next Young GC

  1. Results of young GC in G1

Surviving objects are evacuated to survivor region or old Region

G1 Young GC summary

In general, the Young GC in G1 can be summarized as follows

  • A heap is a block of memory divided into regions
  • The young memory space is a combination of discrete regions, which makes resizing simple
  • The Young GC will STW and all application threads will be paused
  • The Young GC uses multiple threads to do this in parallel
  • Surviving objects are copied to a new survivor or old region

G1 Recovery phase – Parallel marking cycle phase

The G1 old generation performs the following steps (note that part of the phase is part of the young generation collection)

phase describe
(1) Initial marker (STW) This is an STW event that runs on a normal Young GC, and the tag probably references an older survivor region(root region).
(2) Root region scanning Scanning survivor Region for references with older ages, while the application is still running, must be completed before the Young GC occurs
(3) Parallel marking The whole heap is found alive while the application is still running, and this phase can be interrupted by young generation garbage collection
(4) Relabel (STW) Complete the marking of surviving objects in the heap using snapshot-at-the-beginning(SATB) algorithm
(5) Clear (STW and concurrency) Record live objects and completely free regions (STW); Clean the RSet (STW); Reset empty Regoin, return to free list (concurrent)
(*) copy (STW) Copy (or evacuate) live objects to unused regions using [GC Pause (young)] in young GC and [GC Pause (mixed) in old gc at the same time

Look at the old GC in G1 step by step

  1. Initial tag. You can see tokens like GC Pause (young)(initial-mark) in the GC log

2. Parallel marking. If they find an empty region(marked with an X in the diagram), they immediately clean it up during the remark phase, and they also write down the survival information

3. Re-mark the stage. The empty region is immediately removed and reclaimed, and the region’s survival information is now calculated

4. Copy/clean phase. G1 selects regions with the least amount of survivability that can be collected faster, and these regions are collected together when young gc occurs, as you can see in the log [GC Pause (mixed)], so that both young and old generations are collected at the same time

5. The post-copy/clean phase. The selected regions are recycled and compressed into dark blue and dark green regions, as shown in the figure below

G1 Old GC summary

  • Parallel marking stage
    • Apply runtime parallelism to calculate survivability information
    • Survivability is used to identify which regions are best recovered during the evacuation phase
    • There is no CMS cleanup phase
  • Relabeling stage
    • Faster than CMS using snapshot-at-the-begining(SATB) algorithm
    • A completely empty region is reclaimed at this point
  • Copy/clean phase
    • The young generation is recycled along with the old generation
    • The aged generation is selected based on the number of surviving objects (survivability)

Some parameters for G1 GC

Parameter and default value describe
-XX:+UseG1GC Use the G1 garbage collector
-XX:MaxGCPauseMillis=n Gc target maximum pause time, default 200 ms
-XX:InitiatingHeapOccupancyPercent=n Concurrent GC starts when the old segment occupies this percentage of heap space. The default value is 45%, with 0 indicating a constant number of GC cycles (IHOP for short).
-XX:NewRatio=n The ratio of new to old is 2 by default
-XX:SurvivorRatio=n The Eden /survivor ratio is 8 by default
-XX:MaxTenuringThreshold=n The default value is 15
-XX:ParallelGCThreads=n The number of threads used in the parallel GC phase, the default value depends on the platform on which the JVM is running
-XX:ConcGCThreads=n The number of threads used in the concurrent GC phase, the default value depends on the platform on which the JVM is running
-XX:G1ReservePercent=n The percentage of free memory reserved to reduce the risk of space overflow is 10% by default
-XX:G1HeapRegionSize=n Region size. The minimum value is 1M and the maximum value is 32M
-XX:G1HeapWastePercent=10 When the garbage collection ratio is lower than this value, no mixed GC occurs and the default is 10
-XX:G1OldCSetRegionThresholdPercent=10 The upper limit of aged regions that can be reclaimed during mixed GC
-XX:G1MixedGCLiveThresholdPercent=65 The proportion of the aged generation surviving objects below which will be selected for CSet

Some best practices

  • Do not set the size of the young generation
  • The target pause time is the time it takes to set it to 90% of the time

reference

Getting Started with G1 Gabage Collector

Garbage First Garbage Collector Tuning