JVM -- garbage collection

2, Garbage recycling

  1. How to judge whether an object can be recycled

  2. Garbage collection algorithm

  3. Generational waste recycling

  4. Garbage collector

  5. Garbage collection tuning

1. How to judge whether an object can be recycled

1.1 reference counting method


1.2 reachability analysis algorithm
  • The garbage collector in Java virtual machine uses reachability analysis to explore all living objects
  • Scan the objects in the heap to see if they can be found along the reference chain starting from the GC Root object. If they are not found, they can be recycled
  • Which objects can be used as GC roots?
jsp -- View process id

jmap memory dump 
-dump:format:Format of dump file
live:Actively trigger a garbage collection and only keep the surviving objects
file:The address where the file is saved is the name
jmap -dump:format=b,live,flie=1.bin process id
1.3 four references
  1. Strong reference
  • Only when all GC Roots objects do not reference this object through strong reference can this object be garbage collected
  1. Soft reference
  • When only soft references refer to the object, after garbage collection, when the memory is still insufficient, garbage collection will be started again to collect soft references
  • Object can cooperate with the reference queue to release the soft reference itself
  1. Weak reference
  • When only weak references refer to the object, the weak reference object will be recycled during garbage collection, regardless of whether the memory is sufficient or not
  • The weak reference itself can be released in conjunction with the reference queue
  1. Phantom reference
  • It must be used with reference queue, mainly with ByteBuffer. When the referenced object is recycled, the virtual reference will be queued,

    The Reference Handler thread calls the virtual reference related methods to free the direct memory

  1. Finalizer reference
  • No manual coding is required, but it is used internally with reference queue. During garbage collection, the finalizer references the queued (referenced object)

    It is not recycled for the time being), and then the Finalizer thread finds the referenced object through the Finalizer reference and calls its finalize

    Method, and the referenced object can only be recycled at the second GC

1.3.1 soft reference
 * Demo soft reference
 * -Xmx20m -XX:+PrintGCDetails -verbose:gc
public class Demo2_3 {

    private static final int _4MB = 4 * 1024 * 1024;

    public static void main(String[] args) throws IOException {
        /*List<byte[]> list = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            list.add(new byte[_4MB]);


    public static void soft() {
        // list --> SoftReference --> byte[]

        List<SoftReference<byte[]>> list = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            SoftReference<byte[]> ref = new SoftReference<>(new byte[_4MB]);

        System.out.println("End of cycle:" + list.size());
        for (SoftReference<byte[]> ref : list) {
 // Insufficient memory for a garbage collection
[GC (Allocation Failure) [PSYoungGen: 1988K->488K(6144K)] 14276K->12992K(19968K), 0.0193384 secs] [Times: user=0.00 sys=0.00, real=0.02 secs] 
 // Insufficient memory for a garbage collection
[GC (Allocation Failure) --[PSYoungGen: 4696K->4696K(6144K)] 17200K->17216K(19968K), 0.0010912 secs] [Times: user=0.03 sys=0.00, real=0.00 secs] 
[Full GC (Ergonomics) [PSYoungGen: 4696K->4547K(6144K)] [ParOldGen: 12520K->12480K(13824K)] 17216K->17027K(19968K), [Metaspace: 3281K->3281K(1056768K)], 0.0182133 secs] [Times: user=0.00 sys=0.00, real=0.02 secs] 
// After a complete garbage collection, the memory is still insufficient. Recycle soft references
[GC (Allocation Failure) --[PSYoungGen: 4547K->4547K(6144K)] 17027K->17027K(19968K), 0.0075552 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
[Full GC (Allocation Failure) [PSYoungGen: 4547K->0K(6144K)] [ParOldGen: 12480K->625K(8704K)] 17027K->625K(14848K), [Metaspace: 3281K->3281K(1056768K)], 0.0249965 secs] [Times: user=0.00 sys=0.00, real=0.03 secs] 
 Cycle end: 5
 PSYoungGen      total 6144K, used 4376K [0x00000000ff980000, 0x0000000100000000, 0x0000000100000000)
  eden space 5632K, 77% used [0x00000000ff980000,0x00000000ffdc62f0,0x00000000fff00000)
  from space 512K, 0% used [0x00000000fff00000,0x00000000fff00000,0x00000000fff80000)
  to   space 512K, 0% used [0x00000000fff80000,0x00000000fff80000,0x0000000100000000)
 ParOldGen       total 8704K, used 625K [0x00000000fec00000, 0x00000000ff480000, 0x00000000ff980000)
  object space 8704K, 7% used [0x00000000fec00000,0x00000000fec9c5e8,0x00000000ff480000)
 Metaspace       used 3288K, capacity 4500K, committed 4864K, reserved 1056768K
  class space    used 360K, capacity 388K, committed 512K, reserved 1048576K

 * Demonstrate soft reference, cooperate with reference queue
public class Demo2_4 {
    private static final int _4MB = 4 * 1024 * 1024;

    public static void main(String[] args) {
        List<SoftReference<byte[]>> list = new ArrayList<>();

        // Reference queue
        ReferenceQueue<byte[]> queue = new ReferenceQueue<>();

        for (int i = 0; i < 5; i++) {
            // The reference queue is associated. When the byte [] associated with the soft reference is recycled, the soft reference will be added to the queue itself
            SoftReference<byte[]> ref = new SoftReference<>(new byte[_4MB], queue);

        // Get the useless soft reference object from the queue and remove it
        Reference<? extends byte[]> poll = queue.poll();
        while( poll != null) {
            poll = queue.poll();

        for (SoftReference<byte[]> reference : list) {


1.3.2 weak reference
 * Show me weak references
 * -Xmx20m -XX:+PrintGCDetails -verbose:gc
public class Demo2_5 {
    private static final int _4MB = 4 * 1024 * 1024;

    public static void main(String[] args) {
        //  list --> WeakReference --> byte[]
        // The reference itself also needs a certain amount of memory. The tenth time, the memory is insufficient, resulting in fullgc
        List<WeakReference<byte[]>> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            WeakReference<byte[]> ref = new WeakReference<>(new byte[_4MB]);
            for (WeakReference<byte[]> w : list) {
                System.out.print(w.get()+" ");

        System.out.println("End of cycle:" + list.size());
[B@6d6f6e28 [B@135fbaa4 
[B@6d6f6e28 [B@135fbaa4 [B@45ee12a7 
[GC (Allocation Failure) [PSYoungGen: 1988K->488K(6144K)] 14276K->13008K(19968K), 0.0117709 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 
[B@6d6f6e28 [B@135fbaa4 [B@45ee12a7 [B@330bedb4 
[GC (Allocation Failure) [PSYoungGen: 4696K->496K(6144K)] 17216K->13056K(19968K), 0.0017718 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[B@6d6f6e28 [B@135fbaa4 [B@45ee12a7 null [B@2503dbd3 
[GC (Allocation Failure) [PSYoungGen: 4703K->440K(6144K)] 17263K->13000K(19968K), 0.0005707 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[B@6d6f6e28 [B@135fbaa4 [B@45ee12a7 null null [B@4b67cf4d 
[GC (Allocation Failure) [PSYoungGen: 4646K->440K(6144K)] 17206K->13000K(19968K), 0.0004702 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[B@6d6f6e28 [B@135fbaa4 [B@45ee12a7 null null null [B@7ea987ac 
[GC (Allocation Failure) [PSYoungGen: 4646K->456K(6144K)] 17206K->13016K(19968K), 0.0007407 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[B@6d6f6e28 [B@135fbaa4 [B@45ee12a7 null null null null [B@12a3a380 
[GC (Allocation Failure) [PSYoungGen: 4662K->456K(5120K)] 17222K->13016K(18944K), 0.0038538 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[B@6d6f6e28 [B@135fbaa4 [B@45ee12a7 null null null null null [B@29453f44 
[GC (Allocation Failure) [PSYoungGen: 4642K->32K(5632K)] 17202K->13024K(19456K), 0.0012449 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (Ergonomics) [PSYoungGen: 32K->0K(5632K)] [ParOldGen: 12992K->643K(8192K)] 13024K->643K(13824K), [Metaspace: 3281K->3281K(1056768K)], 0.0168787 secs] [Times: user=0.02 sys=0.00, real=0.02 secs] 
null null null null null null null null null [B@5cad8086 
End of cycle: 10
 PSYoungGen      total 5632K, used 4370K [0x00000000ff980000, 0x0000000100000000, 0x0000000100000000)
  eden space 4608K, 94% used [0x00000000ff980000,0x00000000ffdc4b68,0x00000000ffe00000)
  from space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
  to   space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
 ParOldGen       total 8192K, used 643K [0x00000000fec00000, 0x00000000ff400000, 0x00000000ff980000)
  object space 8192K, 7% used [0x00000000fec00000,0x00000000feca0f18,0x00000000ff400000)
 Metaspace       used 3288K, capacity 4500K, committed 4864K, reserved 1056768K
  class space    used 359K, capacity 388K, committed 512K, reserved 1048576K

2. Garbage collection algorithm

2.1 mark removal

Definition: Mark Sweep

  • Faster speed

  • It will cause memory fragmentation (if a large object is put in at this time, it will be unable to put in due to discontinuous memory)

2.2 marking and sorting

Definition: Mark Compact

  • Slow speed (involving object movement and address change)
  • No memory fragments (move the available objects forward to fill the fragments cleared by the memory and make the memory continuous)

2.3 reproduction

2.3 reproduction

Definition: Copy

  • No memory fragmentation

  • Double memory required

Copy the living objects in the FROM TO to, then empty all the garbage in the FROM, and finally exchange the location of the FROM and TO, FROM - > TO, TO - > FROM

3. Generational waste recycling

Combined with the previous three algorithms

Like a residential building, if the cleaner collects garbage door to door, the efficiency is too slow. Generally, a small garbage dump will be set downstairs, such as disposable chopsticks, express packaging, etc., which need to be cleaned regularly (new generation), but like the broken chairs at home (old age), they don't want to throw them away. They will be put into the small garbage dump downstairs only when the house space can't be put down.

  • Objects are first assigned to the garden of Eden area

  • When the Cenozoic space is insufficient, minor gc is triggered. The surviving objects of Eden and from are copied into to by copy, and the surviving objects are saved

    Object age plus 1 and swap from to

  • minor gc will trigger stop the world and suspend the threads of other users. The user thread will resume running only after the garbage collection is completed

  • When the object life exceeds the threshold, it will be promoted to the old age. The maximum life is 15 (4bit), which does not have to exceed 15

  • When there is insufficient space in the old age, it will try to trigger minor gc first. If there is still insufficient space later, it will trigger full gc and STW

    The interval is longer. The old garbage cleaning uses mark removal or mark sorting. If full gc is useless, it will be OOM

  • If the new object cannot be placed in the new generation, the old generation will be placed between them

  • If the memory of the new generation of objects is insufficient, the ones with long life of the new generation will be put into the old generation

  • Another thread causing OOM does not cause the unexpected termination of the main thread

3.1 relevant JVM parameters

Initial heap size-Xms
Maximum heap size-Xmx or - XX:MaxHeapSize=size
Cenozoic size-Xmn or (- XX:NewSize=size + -XX:MaxNewSize=size)
Proportion of surviving areas (dynamic)-20: Initialsurvivorratio = ratio and - XX: + useadaptive sizepolicy
Proportion of surviving areas-XX:SurvivorRatio=ratio
Promotion threshold-XX:MaxTenuringThreshold=threshold
Promotion details-XX:+PrintTenuringDistribution
GC details-XX:+PrintGCDetails -verbose:gc
MinorGC before FullGC-XX:+ScavengeBeforeFullGC

4. Garbage collector

serialparNewParallel ScavengeGICMSSerial OldParallel Old
Recycling generationnewnewnewNew, oldoldoldold
algorithmcopycopycopyGenerationMark - clearMarking – finishingMarking – finishing
thread singlemanymanymanymanysinglemany
characteristicstw, simple and efficientMultithreaded version of SerialAdaptive adjustment strategy, high throughputThe heap is divided into region s of the same sizeLow pauseSame as beforeSame as before
  1. serial

    • Single thread

    • Small heap memory, suitable for personal computers

  2. Throughput priority

    • Multithreading

    • Large heap memory, multi-core cpu

    • The shortest STW time per unit time is 0.2, 0.2 = 0.4, and the proportion of garbage collection time is the lowest, which is called high throughput

  3. Response time first

    • Multithreading

    • Large heap memory, multi-core cpu

    • Try to minimize the time of single STW 0.1 0.1 0.1 0.1 0.1 = 0.5

4.1 serial

Serial: works in the new generation and adopts replication

Working in old age

-XX:+UseSerialGC = Serial + SerialOld

4.2 throughput priority


Copy mark collation

  • -20: + useparallelgc ~ - XX: + useparalleloldgc 1.8 is on by default

  • Adopt adaptive size policy: - XX: + useadaptive sizepolicy

  • Objectives:

    Conflict with each other

    • 1/(1+ratio) is generally 19: - XX:GCTimeRatio=ratio

    • Pause time of each garbage collection: - XX:MaxGCPauseMillis=ms

  • Control the number of threads for garbage collection: - XX:ParallelGCThreads=n

4.3 priority of response time

It has a certain impact on throughput

Concurrent mark removal garbage collector next generation replication

-XX:+UseConcMarkSweepGC ~ ``-XX:+UseParNewGC~SerialOld `

Initial marking: - XX: parallelgcthreads = N ~ ` - XX: concgcthreads = threads (generally n/4)`

Control when to recycle: - XX:CMSInitiatingOccupancyFraction=percent 65 by default

Before re marking, conduct a garbage collection for the Cenozoic: - XX:+CMSScavengeBeforeRemark

[the external chain image transfer fails, and the source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-mu0b5sas-1645943871132) (C: \ users \ administrator \ appdata \ roaming \ typora \ typora user images \ image-202202262151141652. PNG)]

4.4 G1

Definition: Garbage First

  • 2004 paper release

  • 2009 JDK 6u14 experience

  • 2012 JDK 7u4 official support

  • 2017 JDK 9 default

Applicable scenario

  • Pay attention to Throughput and Low latency at the same time. The default pause target is 200 ms

  • A large amount of memory will divide the heap into multiple regions of equal size

  • On the whole, it is the marking + sorting algorithm, and the replication algorithm is between the two regions

Relevant JVM parameters




1) G1 garbage collection stage

2) Young Collection
  • Meeting STW

3) Young Collection + CM
  • The initial marking of GC Root will be performed during Young GC

  • When the proportion of heap space occupied in the old age reaches the threshold, the concurrency flag (STW will not be used), which is determined by the following JVM parameters

    -20: Initiating heapcoccupancypercent = percent (45% by default)

4) Mixed Collection

Comprehensive garbage collection will be carried out for E, S and O

  • The final mark will STW

  • Copy evaluation STW

Old age area with the most garbage recycling


5) Full GC
  • SerialGC

    • Garbage collection of new generation memory shortage - minor gc

    • Garbage collection due to insufficient memory in old age - full gc

  • ParallelGC

    • Garbage collection of new generation memory shortage - minor gc

    • Garbage collection due to insufficient memory in old age - full gc

  • CMS

    • Garbage collection of new generation memory shortage - minor gc

    • Out of memory in old age

      • Concurrency failed - full gc
  • G1

    • Garbage collection of new generation memory shortage - minor gc

    • Out of memory in old age

      • Trigger concurrent tags and subsequent mixed collection, and the recovery speed is higher than that of garbage generation
      • When the speed of garbage collection cannot keep up with the speed of garbage generation, multithreading - full gc is performed
6) Young Collection Cross generational reference
  • Cross generational reference of Cenozoic recycling (reference of Cenozoic in old age)

  • Card table and Remembered Set

  • When referencing changes, use post write barrier + dirty card queue

  • Concurrent reform threads updates the recalled set

7) Remark
  • pre-write barrier + satb_mark_queue

8) JDK 8u20 string de duplication
  • Advantages: save a lot of memory

  • Disadvantages: it takes up a little more cpu time, and the recovery time of the new generation increases slightly

Enable string de duplication: - XX: + usestringduplication

String s1 = new String("hello"); // char[]{'h','e','l','l','o'}
String s2 = new String("hello"); // char[]{'h','e','l','l','o'}
  • Put all newly allocated strings into a queue

  • When the new generation is recycled, G1 concurrently checks whether there is string duplication

  • If they have the same value, let them refer to the same char []

  • Note that with string Intern() is different

    • String.intern() focuses on string objects

    • The string de duplication focuses on char []

    • Inside the JVM, different string tables are used

9) JDK 8u40 concurrent tag class unloading

After all objects are marked with concurrency, you can know which classes are no longer used. When all classes of a class loader are no longer used, they are unloaded

Load all the classes it loads

-20: + classunloadingwithconcurrent mark enabled by default

10) JDK 8u60 reclaims giant objects
  • When an object is larger than half of the region, it is called a giant object

  • G1 does not copy giant objects

  • Priority is given to recycling

  • G1 will track all incoming references in the old generation, so that giant objects with incoming reference 0 in the old generation can be used in the new generation

    Dispose of it during garbage collection

11) Adjustment of JDK 9 concurrent mark start time
  • Concurrency marking must be completed before the heap space is full, otherwise it degenerates to FullGC

  • Before JDK 9, you need to use the default 45-xx: initiating heapcoccupancypercent

  • JDK 9 can be adjusted dynamically

    • -20: Initiatinghepoccupancypercent is used to set the initial value

    • Data sampling and dynamic adjustment

    • Always add a safe space

12) JDK 9 more efficient recycling
  • 250 + enhanced

  • 180+bug fix

  • https://docs.oracle.com/en/java/javase/17/gctuning

View virtual machine running parameters
"C:\Program Files\Java\jdk1.8.0_91\bin\java" -XX:+PrintFlagsFinal -version | findstr "GC"

Keywords: Java jvm Back-end

Added by karthikeyan_coder on Sun, 27 Feb 2022 08:55:45 +0200