JVM - garbage collection

garbage collection

  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

Problem: a - > b, B - > A, except that no object references a and B.

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?

MAT tool: https://www.eclipse.org/mat/

jmap grabs memory snapshots:

# b indicates that the dump file is in binary format, live indicates that only live objects are captured (garbage collection will be triggered before snapshot capture), and file indicates the name of the saved file
jmap -dump:format=b,live,file=[fileName.formatName] [pid]

1.3 four references

Solid lines represent strong references and others represent weak references.

1. Strong reference
  • Only when all GC Roots objects do not reference this object through strong reference can this object be garbage collected
2. Soft reference
  • When only the soft reference refers to the object, after garbage collection, if the memory is still insufficient, garbage collection will be started again to recycle the soft reference object
  • The soft reference itself can be released in conjunction with the reference queue
3. Weak reference
  • When only weak references refer to the object, the weakly referenced 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
4. Phantom reference
  • It must be used with reference queue, mainly with ByteBuffer. When the referenced object is recycled, the virtual reference will be queued, and the Reference Handler thread will call the virtual reference related methods to free the direct memory
5. Finalizer reference
  • No manual coding is required, but it is used internally with the reference queue. During garbage collection, the Finalizer references the queue (the referenced object has not been recycled for the time being), and then the Finalizer thread finds the referenced object through the Finalizer reference and calls its finalize method. The referenced object can be recycled at the second GC

Soft reference usage scenario Chestnut:

package top.onefine.jvm.test.t2;

import java.io.IOException;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.List;

/**
 * Demonstrate soft references
 * -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]);
        }

        System.in.read();
    }

}

JVM parameters:

function:

Soft reference:

package top.onefine.jvm.test.t2;

import java.io.IOException;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.List;

/**
 * Demonstrate soft references
 * -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]);
        }

        System.in.read();*/
        soft();
    }

    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(ref.get());
            list.add(ref);
            System.out.println(list.size());
        }
        System.out.println("End of cycle:" + list.size());

        for (SoftReference<byte[]> ref : list) {
            System.out.println(ref.get());
        }
    }
}

JVM parameters:

function:

[B@15db9742
1
[B@6d06d69c
2
[B@7852e922
3
[B@4e25154f
4
[GC (Allocation Failure) --[PSYoungGen: 4998K->4998K(6144K)] 17286K->17406K(19968K), 0.0011695 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (Ergonomics) [PSYoungGen: 4998K->4532K(6144K)] [ParOldGen: 12408K->12390K(13824K)] 17406K->16923K(19968K), [Metaspace: 2654K->2654K(1056768K)], 0.0046520 secs] [Times: user=0.20 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) --[PSYoungGen: 4532K->4532K(6144K)] 16923K->16975K(19968K), 0.0008806 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (Allocation Failure) [PSYoungGen: 4532K->0K(6144K)] [ParOldGen: 12442K->527K(8192K)] 16975K->527K(14336K), [Metaspace: 2654K->2654K(1056768K)], 0.0044023 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[B@70dea4e
5
 Cycle end: 5
null
null
null
null
[B@70dea4e
Heap
 PSYoungGen      total 6144K, used 4265K [0x00000000ff980000, 0x0000000100000000, 0x0000000100000000)
  eden space 5632K, 75% used [0x00000000ff980000,0x00000000ffdaa598,0x00000000fff00000)
  from space 512K, 0% used [0x00000000fff80000,0x00000000fff80000,0x0000000100000000)
  to   space 512K, 0% used [0x00000000fff00000,0x00000000fff00000,0x00000000fff80000)
 ParOldGen       total 8192K, used 527K [0x00000000fec00000, 0x00000000ff400000, 0x00000000ff980000)
  object space 8192K, 6% used [0x00000000fec00000,0x00000000fec83c30,0x00000000ff400000)
 Metaspace       used 2664K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 283K, capacity 386K, committed 512K, reserved 1048576K

Soft reference matching reference queue:

package top.onefine.jvm.test.t2;

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.List;

/**
 * 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);
            System.out.println(ref.get());
            list.add(ref);
            System.out.println(list.size());
        }

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

        System.out.println("===========================");
        for (SoftReference<byte[]> reference : list) {
            System.out.println(reference.get());
        }

    }
}

JVM parameters:

function:

[B@15db9742
1
[B@6d06d69c
2
[B@7852e922
3
[B@4e25154f
4
[GC (Allocation Failure) --[PSYoungGen: 4998K->4998K(6144K)] 17286K->17422K(19968K), 0.0012145 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (Ergonomics) [PSYoungGen: 4998K->4548K(6144K)] [ParOldGen: 12424K->12374K(13824K)] 17422K->16922K(19968K), [Metaspace: 2652K->2652K(1056768K)], 0.0048164 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 
[GC (Allocation Failure) --[PSYoungGen: 4548K->4548K(6144K)] 16922K->17018K(19968K), 0.0009279 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (Allocation Failure) [PSYoungGen: 4548K->0K(6144K)] [ParOldGen: 12470K->526K(8192K)] 17018K->526K(14336K), [Metaspace: 2652K->2652K(1056768K)], 0.0046568 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
[B@70dea4e
5
===========================
[B@70dea4e
Heap
 PSYoungGen      total 6144K, used 4265K [0x00000000ff980000, 0x0000000100000000, 0x0000000100000000)
  eden space 5632K, 75% used [0x00000000ff980000,0x00000000ffdaa598,0x00000000fff00000)
  from space 512K, 0% used [0x00000000fff80000,0x00000000fff80000,0x0000000100000000)
  to   space 512K, 0% used [0x00000000fff00000,0x00000000fff00000,0x00000000fff80000)
 ParOldGen       total 8192K, used 526K [0x00000000fec00000, 0x00000000ff400000, 0x00000000ff980000)
  object space 8192K, 6% used [0x00000000fec00000,0x00000000fec83bf0,0x00000000ff400000)
 Metaspace       used 2662K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 283K, capacity 386K, committed 512K, reserved 1048576K

Weak reference Chestnut:

package top.onefine.jvm.test.t2;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

/**
 * 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[]
        List<WeakReference<byte[]>> list = new ArrayList<>();

        for (int i = 0; i < 15; i++) {
            WeakReference<byte[]> ref = new WeakReference<>(new byte[_4MB]);
            list.add(ref);
            for (WeakReference<byte[]> w : list) {
                System.out.print(w.get() + " ");
            }
            System.out.println();

        }
        System.out.println("End of cycle:" + list.size());
    }
}

JVM parameters:

function:

[B@15db9742 
[B@15db9742 [B@6d06d69c 
[B@15db9742 [B@6d06d69c [B@7852e922 
[B@15db9742 [B@6d06d69c [B@7852e922 [B@4e25154f 
[GC (Allocation Failure) [PSYoungGen: 4998K->496K(6144K)] 17286K->12928K(19968K), 0.0012578 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
null [B@6d06d69c [B@7852e922 [B@4e25154f [B@70dea4e 
[GC (Allocation Failure) [PSYoungGen: 4704K->480K(6144K)] 17136K->12968K(19968K), 0.0004862 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
null [B@6d06d69c [B@7852e922 [B@4e25154f null [B@5c647e05 
[GC (Allocation Failure) [PSYoungGen: 4688K->512K(6144K)] 17176K->13032K(19968K), 0.0006619 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
null [B@6d06d69c [B@7852e922 [B@4e25154f null null [B@33909752 
[GC (Allocation Failure) [PSYoungGen: 4719K->480K(6144K)] 17239K->13056K(19968K), 0.0006388 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
null [B@6d06d69c [B@7852e922 [B@4e25154f null null null [B@55f96302 
[GC (Allocation Failure) [PSYoungGen: 4686K->496K(6144K)] 17263K->13088K(19968K), 0.0003781 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
null [B@6d06d69c [B@7852e922 [B@4e25154f null null null null [B@3d4eac69 
[GC (Allocation Failure) [PSYoungGen: 4702K->496K(5120K)] 17294K->13104K(18944K), 0.0003471 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
null [B@6d06d69c [B@7852e922 [B@4e25154f null null null null null [B@42a57993 
[GC (Allocation Failure) [PSYoungGen: 4682K->64K(5632K)] 17290K->13080K(19456K), 0.0004060 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (Ergonomics) [PSYoungGen: 64K->0K(5632K)] [ParOldGen: 13016K->538K(8192K)] 13080K->538K(13824K), [Metaspace: 2656K->2656K(1056768K)], 0.0042214 secs] [Times: user=0.20 sys=0.00, real=0.00 secs] 
null null null null null null null null null null [B@75b84c92 
null null null null null null null null null null [B@75b84c92 [B@6bc7c054 
null null null null null null null null null null [B@75b84c92 [B@6bc7c054 [B@232204a1 
null null null null null null null null null null [B@75b84c92 [B@6bc7c054 [B@232204a1 [B@4aa298b7 
[GC (Allocation Failure) --[PSYoungGen: 4186K->4186K(5632K)] 17012K->17012K(19456K), 0.0007192 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (Ergonomics) [PSYoungGen: 4186K->0K(5632K)] [ParOldGen: 12826K->538K(11264K)] 17012K->538K(16896K), [Metaspace: 2658K->2658K(1056768K)], 0.0048889 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
null null null null null null null null null null null null null null [B@7d4991ad 
Cycle end: 15
Heap
 PSYoungGen      total 5632K, used 4417K [0x00000000ff980000, 0x0000000100000000, 0x0000000100000000)
  eden space 4608K, 95% used [0x00000000ff980000,0x00000000ffdd06e8,0x00000000ffe00000)
  from space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
  to   space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
 ParOldGen       total 11264K, used 538K [0x00000000fec00000, 0x00000000ff700000, 0x00000000ff980000)
  object space 11264K, 4% used [0x00000000fec00000,0x00000000fec869f0,0x00000000ff700000)
 Metaspace       used 2666K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 283K, capacity 386K, committed 512K, reserved 1048576K

2. Garbage collection algorithm

2.1 mark removal

Definition: Mark Sweep

  • Advantages: faster
  • Can cause memory fragmentation

2.2 marking and sorting

Definition: Mark Compact

  • Slow speed
  • Advantages: no memory fragmentation

2.3 reproduction

Definition: Copy

  • No memory fragmentation
  • Double memory required

Swap From and To after replication

3. Generational waste recycling

  • 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 to to by copy. The age of the surviving objects is increased by 1, and the from and to are exchanged
  • 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, and the maximum life is 15 (4bit)
  • When the space in the old age is insufficient, it will try to trigger minor gc first. If the space is still insufficient later, it will trigger full gc and STW(stop the world) for a longer time

Related VM parameters

meaningparameter
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
  • When the space of the new generation is not enough, it will be directly put into the old age
  • The memory overflow in the thread will not affect the operation of the main thread
package top.onefine.jvm.test.t2;

import java.util.ArrayList;

/**
 * Demonstrate memory allocation strategies
 */
public class Demo2_1 {
    private static final int _512KB = 512 * 1024;
    private static final int _1MB = 1024 * 1024;
    private static final int _6MB = 6 * 1024 * 1024;
    private static final int _7MB = 7 * 1024 * 1024;
    private static final int _8MB = 8 * 1024 * 1024;

    // -Xms20M -Xmx20M -Xmn10M -XX:+UseSerialGC -XX:+PrintGCDetails -verbose:gc -XX:-ScavengeBeforeFullGC
    // -20: + useserialgc is a garbage collector
    public static void main(String[] args) throws InterruptedException {
        new Thread(() -> {
            ArrayList<byte[]> list = new ArrayList<>();
            list.add(new byte[_8MB]);
            list.add(new byte[_8MB]);
        }).start();

        System.out.println("sleep....");
        Thread.sleep(2000L);
        System.out.println("main end.");
    }
}

JVM parameters:

Execution:

sleep....
[GC (Allocation Failure) [DefNew: 2790K->745K(9216K), 0.0012293 secs][Tenured: 8192K->8935K(10240K), 0.0017947 secs] 10982K->8935K(19456K), [Metaspace: 3585K->3585K(1056768K)], 0.0030957 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (Allocation Failure) [Tenured: 8935K->8885K(10240K), 0.0015058 secs] 8935K->8885K(19456K), [Metaspace: 3585K->3585K(1056768K)], 0.0015260 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
Exception in thread "Thread-0" java.lang.OutOfMemoryError: Java heap space
	at top.onefine.jvm.test.t2.Demo2_1.lambda$main$0(Demo2_1.java:21)
	at top.onefine.jvm.test.t2.Demo2_1$$Lambda$1/531885035.run(Unknown Source)
	at java.lang.Thread.run(Thread.java:748)
main end.
Heap
 def new generation   total 9216K, used 382K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
  eden space 8192K,   4% used [0x00000000fec00000, 0x00000000fec5fac8, 0x00000000ff400000)
  from space 1024K,   0% used [0x00000000ff500000, 0x00000000ff500000, 0x00000000ff600000)
  to   space 1024K,   0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff500000)
 tenured generation   total 10240K, used 8885K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
   the space 10240K,  86% used [0x00000000ff600000, 0x00000000ffead5e0, 0x00000000ffead600, 0x0000000100000000)
 Metaspace       used 3610K, capacity 4622K, committed 4864K, reserved 1056768K
  class space    used 394K, capacity 454K, committed 512K, reserved 1048576K

4. Garbage collector

  1. serial
  • Single thread
  • Small heap memory, suitable for personal computers
  1. Throughput priority
  • Multithreading
  • Large heap memory, multi-core cpu
  • In the unit time, the shortest STW time is 0.2, 0.2 = 0.4, and the proportion of garbage collection time is the lowest, which is called high throughput
  1. Response time first
  • Multithreading
  • Large heap memory, multi-core cpu
  • Keep the time of single STW as short as possible 0.1 0.1 0.1 0.1 0.1 = 0.1

4.1 serial

-XX:+UseSerialGC = Serial + SerialOld

  • Serial: new generation, using replication algorithm
  • SerialOld: in the old age, the marking + sorting algorithm is adopted

4.2 throughput priority

-XX:+UseParallelGC ~ -XX:+UseParallelOldGC

-XX:+UseAdaptiveSizePolicy

-XX:GCTimeRatio=ratio

-XX:MaxGCPauseMillis=ms

-XX:ParallelGCThreads=n

4.3 response time first (CMS)

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

-XX:ParallelGCThreads=n ~ -XX:ConcGCThreads=threads

-XX:CMSInitiatingOccupancyFraction=percent

-XX:+CMSScavengeBeforeRemark

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

-XX:+UseG1GC
-XX:G1HeapRegionSize=size
-XX:MaxGCPauseMillis=time

1) G1 garbage collection stage

2) Young Collection

  • Meeting STW



3) Young Collection + CM

  • 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: Initiatinghepoccupancypercent = percent (default 45%)

4) Mixed Collection

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

  • The final mark will STW
  • Copy evaluation STW

-XX:MaxGCPauseMillis=ms

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
  • G1
    • Garbage collection of new generation memory shortage - minor gc
    • Out of memory in old age

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 revision 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: slightly more cpu time is used, and the recovery time of the new generation is slightly increased

-XX:+UseStringDeduplication

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 unlike String.intern()
    • String.intern() focuses on string objects
    • The string de duplication focuses on char []
    • Within 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, you can unload all classes loaded by it

-20: + classunloadingwithconcurrent mark enabled by default

10) JDK 8u60 reclaims Jumbo 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 of 0 in the old generation can be disposed of during garbage collection in the new generation

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 - XX: initiatinghepoccupancypercent
  • 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

5. Garbage collection tuning

Preparatory knowledge

  • Master the VM parameters related to GC and be able to adjust the basic space
  • Master relevant tools
  • Understand this: tuning is related to application and environment. There is no universal rule

To view virtual machine operating parameters:

C:\Users\onefine>java -XX:+PrintFlagsFinal -version | findstr "GC"
    uintx AdaptiveSizeMajorGCDecayTimeScale         = 10                                  {product}
    uintx AutoGCSelectPauseMillis                   = 5000                                {product}
     bool BindGCTaskThreadsToCPUs                   = false                               {product}
    uintx CMSFullGCsBeforeCompaction                = 0                                   {product}
    uintx ConcGCThreads                             = 0                                   {product}
     bool DisableExplicitGC                         = false                               {product}
     bool ExplicitGCInvokesConcurrent               = false                               {product}
     bool ExplicitGCInvokesConcurrentAndUnloadsClasses  = false                               {product}
    uintx G1MixedGCCountTarget                      = 8                                   {product}
    uintx GCDrainStackTargetSize                    = 64                                  {product}
    uintx GCHeapFreeLimit                           = 2                                   {product}
    uintx GCLockerEdenExpansionPercent              = 5                                   {product}
     bool GCLockerInvokesConcurrent                 = false                               {product}
    uintx GCLogFileSize                             = 8192                                {product}
    uintx GCPauseIntervalMillis                     = 0                                   {product}
    uintx GCTaskTimeStampEntries                    = 200                                 {product}
    uintx GCTimeLimit                               = 98                                  {product}
    uintx GCTimeRatio                               = 99                                  {product}
     bool HeapDumpAfterFullGC                       = false                               {manageable}
     bool HeapDumpBeforeFullGC                      = false                               {manageable}
    uintx HeapSizePerGCThread                       = 87241520                            {product}
    uintx MaxGCMinorPauseMillis                     = 4294967295                          {product}
    uintx MaxGCPauseMillis                          = 4294967295                          {product}
    uintx NumberOfGCLogFiles                        = 0                                   {product}
     intx ParGCArrayScanChunk                       = 50                                  {product}
    uintx ParGCDesiredObjsFromOverflowList          = 20                                  {product}
     bool ParGCTrimOverflow                         = true                                {product}
     bool ParGCUseLocalOverflow                     = false                               {product}
    uintx ParallelGCBufferWastePct                  = 10                                  {product}
    uintx ParallelGCThreads                         = 13                                  {product}
     bool ParallelGCVerbose                         = false                               {product}
     bool PrintClassHistogramAfterFullGC            = false                               {manageable}
     bool PrintClassHistogramBeforeFullGC           = false                               {manageable}
     bool PrintGC                                   = false                               {manageable}
     bool PrintGCApplicationConcurrentTime          = false                               {product}
     bool PrintGCApplicationStoppedTime             = false                               {product}
     bool PrintGCCause                              = true                                {product}
     bool PrintGCDateStamps                         = false                               {manageable}
     bool PrintGCDetails                            = false                               {manageable}
     bool PrintGCID                                 = false                               {manageable}
     bool PrintGCTaskTimeStamps                     = false                               {product}
     bool PrintGCTimeStamps                         = false                               {manageable}
     bool PrintHeapAtGC                             = false                               {product rw}
     bool PrintHeapAtGCExtended                     = false                               {product rw}
     bool PrintJNIGCStalls                          = false                               {product}
     bool PrintParallelOldGCPhaseTimes              = false                               {product}
     bool PrintReferenceGC                          = false                               {product}
     bool ScavengeBeforeFullGC                      = true                                {product}
     bool TraceDynamicGCThreads                     = false                               {product}
     bool TraceParallelOldGCTasks                   = false                               {product}
     bool UseAdaptiveGCBoundary                     = false                               {product}
     bool UseAdaptiveSizeDecayMajorGCCost           = true                                {product}
     bool UseAdaptiveSizePolicyWithSystemGC         = false                               {product}
     bool UseAutoGCSelectPolicy                     = false                               {product}
     bool UseConcMarkSweepGC                        = false                               {product}
     bool UseDynamicNumberOfGCThreads               = false                               {product}
     bool UseG1GC                                   = false                               {product}
     bool UseGCLogFileRotation                      = false                               {product}
     bool UseGCOverheadLimit                        = true                                {product}
     bool UseGCTaskAffinity                         = false                               {product}
     bool UseMaximumCompactionOnSystemGC            = true                                {product}
     bool UseParNewGC                               = false                               {product}
     bool UseParallelGC                            := true                                {product}
     bool UseParallelOldGC                          = true                                {product}
     bool UseSerialGC                               = false                               {product}
java version "1.8.0_281"
Java(TM) SE Runtime Environment (build 1.8.0_281-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.281-b09, mixed mode)

C:\Users\onefine>

5.1 tuning field

  • Memory
  • Lock competition
  • cpu occupation
  • io

5.2 determination of objectives

  • [low latency] or [high throughput], select the appropriate recycler
  • CMS, G1, ZGC: low latency
  • ParallelGC: high throughput

Virtual machines other than HotSpot:

  • Zing

5.3 fastest GC

The answer is no GC

  • Check the memory usage before and after FullGC and consider the following issues
    • Is there too much data?
      • esultSet = statement.executeQuery("select * from large table limit n")
    • Is the data representation too bloated?
      • Object graph
      • Object size 16 Integer 24 int 4
    • Is there a memory leak?
      • static Map map =
      • soft
      • weak
      • Third party cache implementation

5.4 Cenozoic optimization

  • Characteristics of Cenozoic

    • The memory allocation for all new operations is very cheap
      • TLAB thread-local allocation buffer
    • The recovery cost of dead objects is zero
    • Most objects die after use
    • Minor GC takes much less time than Full GC
  • The bigger the better?

-Xmn
Sets the initial and maximum size (in bytes) of the heap for the young generation (nursery). GC is performed in this region more often than in other regions. If the size for the young generation is too small, then a lot of minor garbage collections are performed. If the size is too large, then only full garbage collections are performed, which can take a long time to complete. Oracle recommends that you keep the size for the young generation greater than 25% and less than 50% of the overall heap size.

  • The new generation can accommodate all [concurrency * (request response)] data
  • The surviving area is large enough to retain [current active object + object requiring promotion]
  • The promotion threshold is properly configured to promote long-lived objects as soon as possible
    -XX:MaxTenuringThreshold=threshold
    -XX:+PrintTenuringDistribution
Desired survivor size 48286924 bytes, new threshold 10 (max 10)
- age 1: 28992024 bytes, 28992024 total
- age 2: 1366864 bytes, 30358888 total
- age 3: 1425912 bytes, 31784800 total
...

5.5 old age tuning

Take CMS as an example

  • In the old days of CMS, the larger the memory, the better
  • Try not to do tuning first. If there is no Full GC, it is OK. Try tuning the new generation first
  • Observe the memory occupation of the old age when Full GC occurs, and increase the memory preset of the old age by 1 / 4 ~ 1 / 3
    • -XX:CMSInitiatingOccupancyFraction=percent

5.6 cases

  • Case 1 Full GC and Minor GC are frequent
  • Case 2: Full GC occurs during the peak period of request, and the single pause time is very long (CMS)
  • Case 3: Full GC (CMS jdk1.7) occurs when the old age is abundant

Tags: Java jvm gc

Posted on Sat, 18 Sep 2021 02:34:19 -0400 by thedarkwinter