- How to judge whether an object can be recycled
- Garbage collection algorithm
- Generational waste recycling
- Garbage collector
- 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
- 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
- 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
- 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
- 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
meaningparameterInitial heap size-XmsMaximum heap size-Xmx or - XX:MaxHeapSize=sizeCenozoic size-Xmn or (- XX:NewSize=size + -XX:MaxNewSize=size)Proportion of surviving areas (dynamic)-20: Initialsurvivorratio = ratio and - XX: + useadaptive sizepolicyProportion of surviving areas-XX:SurvivorRatio=ratioPromotion threshold-XX:MaxTenuringThreshold=thresholdPromotion details-XX:+PrintTenuringDistributionGC details-XX:+PrintGCDetails -verbose:gcMinorGC 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
- serial
- Single thread
- Small heap memory, suitable for personal computers
- 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
- 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
- Meeting STW
- 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%)
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
-
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
- pre-write barrier + satb_mark_queue
- 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
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
- 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
- 250 + enhanced
- 180+bug fix
- https://docs.oracle.com/en/java/javase/12/gctuning
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 uintx AutoGCSelectPauseMillis = 5000 bool BindGCTaskThreadsToCPUs = false uintx CMSFullGCsBeforeCompaction = 0 uintx ConcGCThreads = 0 bool DisableExplicitGC = false bool ExplicitGCInvokesConcurrent = false bool ExplicitGCInvokesConcurrentAndUnloadsClasses = false uintx G1MixedGCCountTarget = 8 uintx GCDrainStackTargetSize = 64 uintx GCHeapFreeLimit = 2 uintx GCLockerEdenExpansionPercent = 5 bool GCLockerInvokesConcurrent = false uintx GCLogFileSize = 8192 uintx GCPauseIntervalMillis = 0 uintx GCTaskTimeStampEntries = 200 uintx GCTimeLimit = 98 uintx GCTimeRatio = 99 bool HeapDumpAfterFullGC = false bool HeapDumpBeforeFullGC = false uintx HeapSizePerGCThread = 87241520 uintx MaxGCMinorPauseMillis = 4294967295 uintx MaxGCPauseMillis = 4294967295 uintx NumberOfGCLogFiles = 0 intx ParGCArrayScanChunk = 50 uintx ParGCDesiredObjsFromOverflowList = 20 bool ParGCTrimOverflow = true bool ParGCUseLocalOverflow = false uintx ParallelGCBufferWastePct = 10 uintx ParallelGCThreads = 13 bool ParallelGCVerbose = false bool PrintClassHistogramAfterFullGC = false bool PrintClassHistogramBeforeFullGC = false bool PrintGC = false bool PrintGCApplicationConcurrentTime = false bool PrintGCApplicationStoppedTime = false bool PrintGCCause = true bool PrintGCDateStamps = false bool PrintGCDetails = false bool PrintGCID = false bool PrintGCTaskTimeStamps = false bool PrintGCTimeStamps = false bool PrintHeapAtGC = false bool PrintHeapAtGCExtended = false bool PrintJNIGCStalls = false bool PrintParallelOldGCPhaseTimes = false bool PrintReferenceGC = false bool ScavengeBeforeFullGC = true bool TraceDynamicGCThreads = false bool TraceParallelOldGCTasks = false bool UseAdaptiveGCBoundary = false bool UseAdaptiveSizeDecayMajorGCCost = true bool UseAdaptiveSizePolicyWithSystemGC = false bool UseAutoGCSelectPolicy = false bool UseConcMarkSweepGC = false bool UseDynamicNumberOfGCThreads = false bool UseG1GC = false bool UseGCLogFileRotation = false bool UseGCOverheadLimit = true bool UseGCTaskAffinity = false bool UseMaximumCompactionOnSystemGC = true bool UseParNewGC = false bool UseParallelGC := true bool UseParallelOldGC = true bool UseSerialGC = false 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
- Is there too much data?
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 memory allocation for all new operations is very cheap
-
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