Today continue the third GC series, staying up late is not easy, welcome one button three even, give an encouragement, don’t like it also doesn’t matter, I can, thank you for your support [wu face].


Common garbage collector combination Settings

You can see how to enable the command to use the specified garbage collection on the Oracle website:

Docs.oracle.com/javase/8/do…

JVM command-garbage collector combination

Garbage collectors are usually used in combination, and I summarize common combinations of garbage collectors based on the official website.

  • -XX:+UseConcMarkSweepGC

Enable the CMS garbage collector for older generations.

Oracle recommends CMS or G1 (-xx :+UseG1GC) when the throughput-focused garbage collector (-xx :+UseParallelGC) does not meet the latency requirements of the application.

By default, this option is disabled and HotSpot VM automatically selects the collector based on the configuration and JDK version of the machine.

When this option is enabled, the -xx :+UseParNewGC option is automatically turned on and should not be disabled because the following combination of options is not recommended in JDK 8: -xx :+UseConcMarkSweepGC -xx: -useparnewGC.

CMS also uses Serial Old to clean up memory fragments once they have been created in the past.

So, -xx :+UseConcMarkSweepGC=ParNew+CMS+Serial Old

  • -XX:+UseG1GC

Enable the G1 garbage collector.

It is suitable for multiprocessor computers with lots of RAM. It can meet the GC pause time target while maintaining good throughput.

The G1 collector is recommended for applications that require heaps (about 6 GB or more in size) and have limited GC latency requirements (stable and predictable pause times of less than 0.5 seconds).

  • -XX:+UseParallelGC

Use a parallel scavenging garbage collector (also known as a throughput collector) to leverage multiple processors to improve application performance.

By default, this option is disabled and HotSpot automatically selects the collector based on the configuration and JDK version of the machine.

If enabled, the -xx :+UseParallelOldGC option is also automatically enabled unless it is explicitly disabled.

Be insane. -xx :+UseParallelGC= parallelold

  • -XX:+UseParallelOldGC

ParallelOld is used for FullGC. By default, this option is disabled.

-xx :+UseParallelGC Automatically -xx :+UseParallelOldGC.

  • -XX:+UseParNewGC

Support for collection using parallel threads in the young generation.

By default, this option is disabled.

It is automatically enabled when the -xx :+UseConcMarkSweepGC option is set.

In JDK 8, it is not recommended to use the -xx :+UseParNewGC option instead of the -xx :+UseConcMarkSweepGC option, which means that ParNew and CMS should be enabled at the same time.

  • -XX:+UseSerialGC

Enable the Serial GC.

This is usually the best choice for small and simple applications that don’t require any special features from garbage collection.

By default, this option is disabled, and the collector is automatically selected based on the configuration of the machine and the type of JVM.

– XX: + UseSerialGC = Serial New + Serial Old.

View the JDK’s default garbage collector

Use the following command

java -XX:+PrintCommandLineFlags -version
Copy the code

You can view the JDK version you are using, the name of your virtual machine, and the garbage collector you are using.

The JDK 1.8 HotSpot VM default GC is ParallelGC

The default GC jdk1.8

The default GC for JDK 11 HotSpot VM is G1

The default GC for JDK11 is G1

Common JVM command parameters

JVM commands are available at:

Docs.oracle.com/javase/8/do…

HotSpot Parameter classification

  • Standard – at the beginning, all HotSpot supports, for examplejava -version

Ensure that all implementations of the Java Virtual Machine (JVM) support standard options. They are used for common operations, such as checking the JRE version, setting the classpath, enabling verbose output, and so on.

  • Non-standard -x, certain versions of HotSpot support certain commands

Non-standard options are generic options specific to the Java HotSpot VIRTUAL machine, so they are not guaranteed to be supported by all JVM implementations, and they are subject to change. These options start with -x.

  • Unstable -XX starts, may be cancelled in the next release

This is an advanced option that starts with -xx and is not recommended. These are developer options for tuning specific areas of the Java HotSpot VIRTUAL machine operation, which often have specific system requirements and may require privileged access to system configuration parameters. There is also no guarantee that all JVM implementations will support them, and they may change.

Let’s use a program to see how it works by tuning JVM parameters and using JVM commands to use different GC.

Before we start, let’s cover memory leaks and memory spills.

Memory leak: a program fails to release the requested memory after it has requested it. A memory leak may not seem to have a big impact, but it can result in an overflow of memory after it accumulates.

Out of memory: When a program requests memory, there is not enough memory for the applicant to use. For example, the program keeps generating objects until it runs out of memory. OOM is called out of memory.

Memory leakage and memory overflow

And the program:

import java.util.LinkedList;
import java.util.List;

public class GCTest {
    public static void main(String[] args) {
 System.out.println("program start!");  List list = new LinkedList();  for (;;) {  byte[] b = new byte[1024 * 1024];  list.add(b);  }  } } Copy the code

Very simple a section of test code, will certainly produce memory overflow, we use the relevant command to observe.

By default, run code:

[root@basic ~]# java GCTest
program start!
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
 at GCTest.main(GCTest.java:9)
Copy the code

A memory overflow was reported.

If we want to know how to allocate memory, we can add the corresponding JVM parameters at runtime. Here are some common parameters to experiment with.

  • java -XX:+PrintCommandLineFlags GCTest
[root@basic ~]# java -XX:+PrintCommandLineFlags GCTest
-XX:InitialHeapSize=32449856 -XX:MaxHeapSize=519197696 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC 
program start!
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
 at GCTest.main(GCTest.java:9)
Copy the code

-xx :+PrintCommandLineFlags: Prints human-identifiable information about the JVM, such as heap space size and the selected garbage collector.

InitialHeapSize: the InitialHeapSize, calculated based on memory

MaxHeapSize: indicates the maximum heap size

UseCompressedClassPointers: Use compression Class pointer, such as the Object. The Class, compressed – XX: + UseCompressedClassPointer occupy 4 byte in memory, without compression – XX: – UseCompressedClassPointer situation for 8 byte

UseCompressedOops: indicates whether the reference type is compressed. -xx :+UseCompressedOops indicates compression. The compressed reference type occupies 4 bytes in the memory, and the uncompressed reference type occupies 8 bytes.

  • java -Xmn10M -Xms40M -Xmx60M -XX:+PrintCommandLineFlags -XX:+PrintGC GCTest

-Cenozoic size of Xmn

-Xms Specifies the minimum heap size

-Xmx Maximum heap size. The value must be the same as that of Xms to prevent heap bouncing from affecting performance

-xx :+PrintGC Prints GC information

Execute as follows:

[root@basic ~]# java -Xmn10M -Xms40M -Xmx60M -XX:+PrintCommandLineFlags -XX:+PrintGC GCTest
-XX:InitialHeapSize=41943040 -XX:MaxHeapSize=62914560 -XX:MaxNewSize=10485760 -XX:NewSize=10485760 -XX:+PrintCommandLineFlags -XX:+PrintGC -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC 
program start!
[GC (Allocation Failure)  7839K->7592K(39936K), 0.0274278 secs]
[GC (Allocation Failure)  14920K->14704K(39936K), 0.0091149 secs]
[GC (Allocation Failure) 22024K->21872K(39936K), 0.0124746 secs] [GC (Allocation Failure) 29195K->29008K(39936K), 0.0150616 secs] [Full GC (Ergonomics) 29008K->28929K(55296K), 0.0209756 secs] [GC (Allocation Failure) 36254K->36225K(55296K), 0.0102666 secs] [GC (Allocation Failure) 43543K->43393K(55808K), 0.0087281 secs] [Full GC (Ergonomics) 43393K->43265K(60928K), 0.0104380 secs] [GC (Allocation Failure) -- 51630K->58798K(60928K), 0.0100362 secs] [Full GC (Ergonomics) 58798K->51458K(60928K), 0.0055668 secs] [Full GC (Ergonomics) 58793K->58626K(60928K), 0.0045510 secs] [Allocation Failure Full GC 58626K->58614K(60928K), 0.0116986 secs]Exception in thread "main" java.lang.OutOfMemoryError: Java heap space  at GCTest.main(GCTest.java:9) Copy the code

[Allocation Failure (GC) 7839K->7592K(39936K, 0.0274278 secs)] : the generation OF GC. After GC, the heap memory usage is reduced from 7839K to 7592K, and the heap size is 39936K

As can be seen, FGC is generated after multiple YGC:

[Full GC (Ergonomics) 29008K->28929K(55296K, 0.0170423 secs)] : FullGC is generated. After GC, the heap memory usage decreases from 29008K to 28929K

  • java -Xmn10M -Xms40M -Xmx60M -XX:+PrintCommandLineFlags -XX:+PrintGCDetails GCTest

-xx :+PrintGCDetails To print more detailed GC information:

[root@basic ~]# java -Xmn10M -Xms40M -Xmx60M -XX:+PrintCommandLineFlags -XX:+PrintGCDetails GCTest
-XX:InitialHeapSize=41943040 -XX:MaxHeapSize=62914560 -XX:MaxNewSize=10485760 -XX:NewSize=10485760 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC 
program start!
[Allocation Failure (GC) [PSYoungGen: 7839K->352K(9216K)] 7839K->7528K(39936K), 0.0074573 secs] [Times: User sys = = 0.00 0.01, real = 0.00 secs][Allocation Failure (GC) [PSYoungGen: 7680K->320K(9216K)] 14856K->14664K(39936K), 0.0070717 secs] [Times: User sys = = 0.00 0.02, real = 0.01 secs][Allocation Failure (GC) [PSYoungGen: 7640K->320K(9216K)] 21984K->21832K(39936K), 0.0064630 secs] [Times: User sys = = 0.01 0.01, real = 0.00 secs][Allocation Failure (GC) [PSYoungGen: 7643K->320K(9216K)] 29155K->29000K(39936K), 0.0070857 secs] [Times: User sys = = 0.01 0.02, real = 0.00 secs][Full GC (Ergonomics) [PSYoungGen: 320K->0K(9216K)] [ParOldGen: 28680K->28929K(46080K)] 29000K->28929K(55296K), [Metaspace: 2514K->2514K(1056768K)], 0.0181374 secs] [Times: User sys = = 0.04 0.01, real = 0.02 secs][PSYoungGen: 7325K->128K(9216K)] 36254K->36225K(55296K), 0.0090166 secs] [Times: User sys = = 0.01 0.01, real = 0.01 secs][Allocation Failure (GC) [PSYoungGen: 7446K->128K(9728K)] 43543K->43393K(55808K), 0.0045376 secs] [Times: User sys = = 0.01 0.00, real = 0.01 secs][Full GC (Ergonomics) [PSYoungGen: 128K->0K(9728K)] [ParOldGen: 43265K->43265K(51200K)] 43393K->43265K(60928K), [Metaspace: 2514K->2514K(1056768K)], 0.0076301 secs] [Times: User sys = = 0.01 0.02, real = 0.01 secs][Allocation Failure (GC) --[PSYoungGen: 8365K->8365K(9728K)] 51630K->58798K(60928K), 0.0056167 secs] [Times: User sys = = 0.00 0.01, real = 0.00 secs][Full GC (Ergonomics) [PSYoungGen: 8365K->1024K(9728K)] [ParOldGen: [Times: 50433K->50433K(51200K)] 50798K ->51458K(60928K), [Metaspace: 2514K->2514K(1056768K)], 0.0113353 secs] [Times: User sys = = 0.02 0.01, real = 0.02 secs][Full GC (Ergonomics) [PSYoungGen: 8360K->8192K(9728K)] [ParOldGen: [Metaspace: 2514K->2514K(1056768K)], secs] [Times: User sys = = 0.00 0.01, real = 0.00 secs][Full GC (Allocation Failure) [PSYoungGen: 8192K->8192K(9728K)] [ParOldGen: 50433K->50422K(51200K)] 58626K->58614K(60928K), [Metaspace: 2514K->2514K(1056768K)], 0.0181221 secs] [Times: User sys = = 0.04 0.00, real = 0.02 secs]Exception in thread "main" java.lang.OutOfMemoryError: Java heap space  at GCTest.main(GCTest.java:9) Heap  PSYoungGen total 9728K, used 8533K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000) Eden space 9216 k, 92% informs [x00000000fff00000 x00000000ff600000 0, 0 x00000000ffe55678, 0)From space, 512 k, 0% 2 [x0000000100000000 x00000000fff80000 0, 0 x00000000fff80000, 0)To space in 512 k, 0% informs [x00000000fff80000 x00000000fff00000 0, 0 x00000000fff00000, 0) ParOldGen total 51200K, used 50422K [0x00000000fc400000, 0x00000000ff600000, 0x00000000ff600000) The object space 51200 k, 98% informs the [x00000000ff600000 x00000000fc400000 0, 0 x00000000ff53d878, 0) Metaspace used 2545K, capacity 4486K, committed 4864K, reserved 1056768K  class space used 275K, capacity 386K, committed 512K, reserved 1048576K Copy the code

In addition, the parameters for GC information are:

-xx :+PrintGCTimeStamps: Prints time stamps on each GC.

– XX: + PrintGCApplicationConcurrentTime: print since last time suspended (such as GC pause) over time.

-xx :+PrintGCDateStamps: Prints the date stamp on each GC.

-xx :+PrintGCTaskTimeStamps: Enables timestamp printing for each individual GC worker task.

  • java -XX:+UseConcMarkSweepGC -XX:+PrintCommandLineFlags -XX:+PrintGC GCTest

This is mainly to look at the CMS garbage collector to switch to the GC process information:

[root@basic ~]# java -XX:+UseConcMarkSweepGC -XX:+PrintCommandLineFlags -XX:+PrintGC GCTest
-XX:InitialHeapSize=32449856 -XX:MaxHeapSize=519197696 -XX:MaxNewSize=172666880 -XX:MaxTenuringThreshold=6 -XX:OldPLABSize=16 -XX:+PrintCommandLineFlags -XX:+PrintGC -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:+UseParNewGC 
program start!
[GC (Allocation Failure)  7865K->7452K(31680K), 0.0055673 secs]
[GC (Allocation Failure)  15815K->15634K(31680K), 0.0051261 secs]
[GC (CMS Initial Mark) 22965K(31680K) 0.0014019 secs][GC (Allocation Failure) 23989K->23956K(33736K), 0.0060109 secs] [GC (Allocation Failure) 32314K->32191K(41960K), 0.0238551 secs] [GC (Allocation Failure) 40551K->40280K(50184K), 0.0254390 secs] [GC (Allocation Failure) 48641K->48486K(58408K), 0.0273632 secs] [GC (Allocation Failure) 56847K->56655K(65796K), 0.0104898 secs] GC (CMS Final Remark) 65017K(65796K), 0.0020809 secs[GC (Allocation Failure) 65017K->64822K(74020K), 0.0080847 secs] [GC (Allocation Failure) 73184K->72985K(116060K), 0.0048156 secs] [GC (Allocation Failure) 81348K->81174K(116060K), 0.0156927 secs] [GC (Allocation Failure) 89536K->89366K(116060K), 0.0164924 secs] GC (CMS Initial Mark) 91585K(116060K), 0.0005150 secs[GC (Allocation Failure) 97729K->97558K(116060K), 0.0200535 secs] [GC (Allocation Failure) 105921K->105749K(116060K), 0.0195895 secs] [GC (Allocation Failure) 114111K->113943K(123256K), 0.0185969 secs] [GC (Allocation Failure) 122306K->122133K(131480K), 0.0174622 secs] [GC (Allocation Failure) 130496K->130328K(139704K), 0.0168396 secs] [GC (Allocation Failure) 138690K->138518K(147928K), 0.0222069 secs] [GC (Allocation Failure) 146881K->146712K(156152K), 0.0189141 secs] [GC (Allocation Failure) 155075K->154903K(164376K), 0.0212268 secs] [GC (Allocation Failure) 163265K->163097K(172600K), 0.0184528 secs] [GC (Allocation Failure) 171460K->171289K(180824K), 0.0230886 secs] [GC (Allocation Failure) 179652K->179482K(189048K), 0.0197197 secs] [GC (Allocation Failure) 187844K->187672K(197272K), 0.0211699 secs] [GC (Allocation Failure) 196035K->195864K(205496K), 0.0219487 secs] [GC (Allocation Failure) 204227K->204056K(213720K), 0.0221430 secs] [GC (Allocation Failure) 212419K->212251K(221944K), 0.0237262 secs] [GC (Allocation Failure) 220613K->220443K(230168K), 0.0274986 secs] [GC (Allocation Failure) 228806K->228635K(238392K), 0.0253731 secs] [GC (Allocation Failure) 236998K->236826K(246616K), 0.0186347 secs] [GC (Allocation Failure) 245188K->245018K(254840K), 0.0188651 secs] [GC (Allocation Failure) 253381K->253212K(263064K), 0.0232380 secs] [GC (Allocation Failure) 261575K->261403K(271288K), 0.0192675secs][GC (Allocation Failure) 269765K->269597K(279512K), 0.0250426 secs] [GC (Allocation Failure) 277960K->277787K(287736K), 0.0230294 secs] [GC (Allocation Failure) 286151K->285982K(295960K), 0.0252418 secs] [GC (Allocation Failure) 294345K->294174K(304184K), 0.0195708 secs] [GC (Allocation Failure) 302537K->302366K(312408K), 0.0252629 secs] [GC (Allocation Failure) 310729K->310559K(320632K), 0.0241283 secs] [GC (Allocation Failure) 318921K->318749K(328856K), 0.0235919 secs] [GC (Allocation Failure) 327112K->326943K(336052K), 0.0204393 secs] [GC (Allocation Failure) 335306K->335133K(344276K), 0.0242358 secs] [Full GC (Allocation Failure) 343496K->343313K(344276K), 0.0948962 secs] [GC (Allocation Failure) 344507K->347589K(349120K), 0.0145370 secs] [Full GC (Allocation Failure) 347589K->344337K(349120K), 0.0053974 secs] [GC (CMS Initial Mark) 345361K(491072K), 0.0031466 secs] [GC (CMS Final Remark) 352315K(491072K), 0.0021340 secs] [Full GC (Allocation Failure) 489533K->488726K(491072K), 0.0355269 secs] [GC (CMS Initial Mark) 489750K(491072K) 0.0017936 secs][Full GC (Allocation Failure) 490513K->489750K(491072K), 0.0029711 secs] [Full GC (Allocation Failure) 489750K->489739K(491072K), 0.0662137 secs] Exception in thread "main" java.lang.OutOfMemoryError: Java heap space  at GCTest.main(GCTest.java:9) Copy the code

At first glance, it looks similar to the default ParallelGC log information, except that it is longer. In fact, it has more CMS Initial Mark, CMS Final Remark, etc.

The concepts of CMS initial tagging and re-tagging were introduced in the previous article:

JVM heap memory generation model and common garbage collector

From this log, it can be seen that the system failed to clear it through several times of FullGC, which eventually led to OOM.

PS GC logs

First look at this sentence:

[Allocation Failure (GC) [PSYoungGen: 7839K->368K(9216K)] 7839K->7544K(39936K), 0.0072850 secs] [Times: User sys = = 0.01 0.02, real = 0.01 secs]

The meaning of this sentence is:

GC: YGC, GC produced in the young generation (Cenozoic).

Allocation Failure: The cause of GC.

PSYoungGen: PS, the new generation.

7839K->368K (9216K) : 7839K before garbage collection and 368K after garbage collection. 9216K is the size of the entire young generation heap.

7839K->7544K(39936K) : The space size of the entire heap changes. Why is the total heap size 7839K, the same as the young generation, no old region? The reason is that it’s all taken up by the younger generation.

0.0072850 SECS: Time of this GC

[Times: user=0.01 sys=0.02, real=0.01 secs] : user indicates the user-mode time, sys indicates the kernel-mode time, and real indicates the actual time

Once an overflow occurs, the GC log dumps the entire heap:

Heap
PSYoungGen      total 9728K, used 8533K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
Eden space 9216 k, 92% informs [x00000000fff00000 x00000000ff600000 0, 0 x00000000ffe55678, 0)From space, 512 k, 0% 2 [x0000000100000000 x00000000fff80000 0, 0 x00000000fff80000, 0)To space in 512 k, 0% informs [x00000000fff80000 x00000000fff00000 0, 0 x00000000fff00000, 0)ParOldGen total 51200K, used 50422K [0x00000000fc400000, 0x00000000ff600000, 0x00000000ff600000) The object space 51200 k, 98% informs the [x00000000ff600000 x00000000fc400000 0, 0 x00000000ff53d878, 0)Metaspace used 2545K, capacity 4486K, committed 4864K, reserved 1056768K  class space used 275K, capacity 386K, committed 512K, reserved 1048576K Copy the code

For example, PSYoungGen is the new generation, Eden is the Eden area in the new generation, from and to are the two survivor areas, ParOldGen is the old age, and Metaspace is the meta-space.

Memory address:

[0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)

[Start address, end address of use space, end address of whole space]Copy the code

Eden space 9216 k, 92% informs [x00000000ff600000 0, 0 x00000000ffe55678, 0 x00000000fff00000) :

The memory address representing the space in Eden is from 0x00000000FF600000 to 0x00000000FFF00000, a total of 9216K, which is 92% used.



The first public line 100 li ER, welcome the old iron attention reading correction. You can also visit GitHub github.com/xblzer/Java…