“This is the fourth day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.”

Hello, I’m looking at the mountains.

These days pressure test pre-production environment, TPS found all kinds of instability. Because it is a reconstructed system, it is said that the original system has no problems at the time of high concurrency, resulting in the reconstruction of the system by dozens of concurrent pressure on all kinds of instability. Although the colleague didn’t say anything, he felt slapped in the face.

So all kinds of investigation, the first thing that comes to mind is the JVM parameters, so optimization, hoping to give a good result. Although it was later proved that the reason for the instability was that the pressure test server installed LoadRunner was not stable, which is not my system’s business, but also for the record, one is to make a backup, and two is to make a reference for others.

The words written in the front

Because the default values of the parameters provided by the Hotspot JDK change from one version to another, the parameters can also affect each other. Moreover, different server configurations can affect the final result. So don’t be superstitious in some online article (including this article) inside the parameter configuration, all the configuration need to personally test some ability to use. -xx :+PrintFlagsFinal To print JVM default values for the current environment, for example: Java – XX: PrintFlagsFinal – version, you can also use the Java/production environment parameters – XX: + PrintFlagsFinal version | grep [to verify the parameters of the] look at specific parameter data.

Here is an 8G server parameter, JDK version information as follows:

Java version "1.8.0_73" Java(TM) SE Runtime Environment (Build 1.8.0_73-B02) Java HotSpot(TM) 64-bit Server VM (build 25.73 - b02, mixed mode)Copy the code

Heap Settings

Heap memory Settings should be a Java program ape basic literacy, at least have to modify Xms, Xmx, Xmn these three parameters. But what is the total memory footprint of a 2GB heap size JVM?

Heap memory + number of threads * Thread stack + permanent generation + binary + out-of-heap memory

2G + 1000 * 1M + 256M + 48/240m + (~ 2G) = 5.5g (3.5g)

• Thread stack: stores local variables (atomic types, references) and others, defaults to 1M• Permanent generation: Stores class definitions and constant pools, note the difference in JDK7/8 • Binary code: • Out-of-heap memory: used by Netty, out-of-heap cache, etc. By default, the maximum value is approximately the size of the heap

That is, if the heap is set to 2 gigabytes, a JVM with 1000 threads might need 5.5 GIGABytes, and an 8 GIGAByte server would start a service, considering system usage, IO usage, and so on. Of course, if the number of threads is small, the concurrency is not high, and the pressure is not high, you can still start multiple, and you can also reduce the heap memory.

  1. -xMS2G and -xmx2G: heap size, the first is the minimum heap memory, the second is the maximum heap memory, the appropriate value is 2-4G, depending on the GC time
  2. -xmn1g or (-xx :NewSize=1g and -xx :MaxNewSize=1g) or -xx :NewRatio=1: Sets the new generation size. The JDK defaults the new generation size to 1/3 of the heap size, i.e-XX:NewRatio=2. So this is set to 1g, which is 1-XX:NewRatio=1. It can be set according to your needs.
  3. -xx :MetaspaceSize=128m; -xx :MaxMetaspaceSize=512m; -xx :MetaspaceSize= 512m; The maximum value of 512 MB is protected.
  4. – XX: SurvivorRatio: The default size of each survivable zone in the new generation is 8, i.e. 1/10 of the new generation, 1/(SurvivorRatio+2).
  5. -xSS256K: Outside the heap, threads occupy stack memory. By default, each thread is 1 MB. Store the stack of method calls, local variables, local variables after scalar replacement, etc., some people like to set a small point to save memory and open more threads. But there’s no need to set it to a smaller size, so some people like to set it to a larger size, especially for recursive calls like JSON parsing.
  6. -xx :MaxDirectMemorySize: size of out-of-heap memory/direct memory. The default value is heap memory minus the size of a Survivor region.
  7. -xx :ReservedCodeCacheSize: indicates the storage area of binary code after JIT compilation. If it is full, it will not be compiled. Default open multi-layer compilation 240M, you can see the size of CodeCache in JMX.

The GC is set

At present, the mainstream GC is CMS and G1, and the god suggested 8G as the boundary. (JDK 9 is said to be G1 by default). The CMS collector is selected because the memory of the application Settings is relatively small. The following parameters are also for the CMS collector and will be supplemented later if necessary for the G1 collector.

The CMS setup

  1. -xx :+UseConcMarkSweepGC: enables the CMS garbage collector
  2. – XX: CMSInitiatingOccupancyFraction = 80 and – XX: + UseCMSInitiatingOccupancyOnly: The two parameters need to be used together, otherwise 75 of the first parameter is just a reference value and the JVM recalculates the GC time.
  3. -xx :MaxTenuringThreshold=15: How many Young GC’s an object has survived in Survivor zones to advance to the old generation. The default is 15. Young GC is the largest source of application pauses, and the number of objects that survive the new generation GC directly affects the pause time, so if you know how often Young GC is executed and the maximum lifetime of most temporary objects in your application, you can make it shorter. Let the new generation of long-term objects, who are not temporary objects, be promoted to the elderly generation.
  4. -xx: -disableexplicitGC: allows you to invoke GC using System.gc() actively. Note that some JVM optimization recommendations are to set -xx: -disableexplicitGC to disable manual calls to System.gc(). This is because system.gc () triggers Full GC, and frequent Full GC can seriously affect performance. But many NIO frameworks, such as Netty, use out-of-heap memory, which cannot be reclaimed without a Full GC. If you do not call System.gc() actively, you have to wait until the JVM itself triggers Full GC, which can cause long pauses (STW) and increase machine load. So instead of completely disabling system.gc () and shortening the time for Full gc, use system.gc ()-XX:+ExplicitGCInvokesConcurrentor-XX:+ExplicitGCInvokesConcurrentAndUnloadsClassesOption to trigger the Full GC using the CMS collector. These two options need to work together-XX:+UseConcMarkSweepGCUse.
  5. – XX: + ExplicitGCInvokesConcurrent: using System. The gc () is triggered when the CMS gc, rather than a Full gc. This option is disabled by default and can only be enabled with the -xx :+UseConcMarkSweepGC option.
  6. – XX: + ExplicitGCInvokesConcurrentAndUnloadsClasses: using System. The gc (), the permanent generation have also been included into the scope of the CMS. This option can only be enabled if you use the -xx :+UseConcMarkSweepGC option.
  7. -xx :+ParallelRefProcEnabled: The default value is false. Parallel processing of Reference objects, such as WeakReference, will not have obvious effect unless there is a log with a long Reference processing time in GC log.
  8. -xx :+ScavengeBeforeFullGC: Performs a Young GC before FullGC.
  9. -xx :+UseGCOverheadLimit: limits the GC running time. If GC takes too long, throw OOM.
  10. -xx :+UseParallelGC: Sets the parallel garbage collector
  11. -xx :+UseParallelOldGC: Sets the old age to use the parallel garbage collector
  12. -xx: -usesERIalgc: closes the serial garbage collector
  13. + CMSParallelInitialMarkEnabled and – – XX: XX: + CMSParallelRemarkEnabled: reduce the tag to a halt
  14. – XX: + CMSScavengeBeforeRemark: The default value is off. Before CMS remark, perform a minor GC to clear the new generation. In this way, the number of new generation objects referenced from the old generation is reduced, and the global CMS remark phase is shorter. If you see that the remark phase in the GC log takes too long, you can open this item to see if it works. Otherwise, do not open this item.
  15. -xx :CMSWaitDuration=10000: Sets the maximum garbage collection interval. The default is 2000.
  16. -xx :+CMSClassUnloadingEnabled: clears expired classes in permanent generation in CMS without waiting until Full GC, JDK7 is off by default and JDK8 is on. Depending on your situation, for example, if you’re running a dynamic language script like Groovy that generates a lot of temporary classes. It increases CMS Remark’s pause time, so if new classes are not being loaded frequently, this parameter should not be turned on.

The GC log

The GC process can be optimized using GC logs.

  1. -xx :+PrintGCDetails: Enables the GC log printing function
  2. -xloggc :/path/to/gc.log: Specifies the GC log location
  3. -xx :+PrintHeapAtGC: displays detailed stack information before and after GC
  4. -xx :+PrintGCDateStamps: Prints a readable date instead of a timestamp
  5. – XX: + PrintGCApplicationStoppedTime: print all cause the JVM pauses, if found some really don’t know what pause, temporary plus again-XX:+PrintSafepointStatistics -XX: PrintSafepointStatisticsCount=1Looking for a reason.
  6. – XX: + PrintGCApplicationConcurrentTime: print the JVM pauses in two uptime, and-XX:+PrintGCApplicationStoppedTimeUse them together for better results.
  7. – XX: + PrintTenuringDistribution: check the new survival after each minor GC cycle threshold
  8. -xx :+UseGCLogFileRotation and -xx :NumberOfGCLogFiles=10 and -xx :GCLogFileSize=10M: GC logs are cleared after a restart, but if an application has not been restarted for a long time, the GC logs will increase, so adding these three parameters will make the GC logs scroll to the file, but if the application is restarted, the name may be confused.
  9. -xx :PrintFLSStatistics=1: Displays statistics about memory fragments before and after each GC

Other Parameter Settings

  1. – EA: Enable assertion, this is not much to say, you can choose to enable, or choose not to enable, there is no big difference. Completely according to their own systems for processing.
  2. -xx :+UseThreadPriorities: Enable thread priorities, mainly because we can give periodic tasks a lower priority to avoid interfering with client work. In my current environment, it is enabled by default.
  3. -xx :ThreadPriorityPolicy=42: Allows the thread priority to be reduced
  4. – XX: + HeapDumpOnOutOfMemoryError: memory leak occurs to heap dump
  5. -xx :HeapDumpPath=/path/to/java_pid.hprof: This parameter is the same as that of-XX:+HeapDumpOnOutOfMemoryErrorSets the content output file for heap-dump.
  6. -xx :ErrorFile=/path/to/hs_err_pid.log: Specifies the fatal error log location. The hs_err_pid.log file is usually output in the JVM when fatal errors occur. By default, it is in the working directory (if you do not have permissions, try to create it in/TMP), but it is better to specify your own location so that it is easy to collect and find, and avoid loss.
  7. -xx :StringTableSize=1000003: Specifies the size of the string constant pool. The default value is 60013. For those of you with a bit of Java savvy, strings are constants that cannot be modified once they are created. The place where these constants reside is called the string constant pool. If there are many string operations in your system, and these string values are relatively fixed, you can appropriately increase the pool size if allowed.
  8. -xx :+AlwaysPreTouch: The memory defined by all parameters is traced at startup. Using this parameter may slow startup, but it will be faster later in memory usage. This ensures that memory pages are allocated continuously and that the GC pauses are not lengthened when the new generation is promoted. It’s usually only noticeable if the ram is larger than 32GB.
  9. -xx: -usebiasedlocking: To disable biased locking (in the environment where a large number of lock objects are created and highly concurrent (that is, non-multi-threaded high-concurrent applications), disabling biased locking can bring certain performance optimization)
  10. -xx :AutoBoxCacheMax=20000: Increase the automatic boxing range of digital objects. The JDK defaults to -128 to 127 ints and longs.
  11. – XX: – OmitStackTraceInFastThrow: don’t ignore repeated abnormal stack, this is the optimization of the JDK, a large number of repeated JDK exception no longer print the StackTrace. If your system does not restart for a long time, the JDK will ignore the result of running N exceptions in the same place, and you will not see the specific StackTrace when viewing the log.
  12. -xx :+ perflesharedmem: enables standard memory usage. JVM control is divided into standard or shared memory, the difference is that one is in JVM memory, the other is to generate/TMP/hsperfData_ {userID}/{PID} file, store statistics, map to memory through Mmap, other processes can access the content through the file. This parameter prevents the JVM from writing statistics to files at the expense of JPS, jstat, and JMX. However, JPS, Jstat and other small tools are very useful when troubleshooting problems. They are much more useful than the heavy stuff like JMX, so you need to choose between them. Here is an example of a GC pause.
  13. – Djava.net.preferIPv4Stack=true: this parameter is a parameter of the network problems, can be set according to need. On some machines with ipv6 enabled, passInetAddress.getLocalHost().getHostName()It is possible to obtain the full machine name, but on ipv4 machines, it is possible to obtain the full machine name by using this parameter.

The example given by the great God

The following examples given by daishen can be used for reference, but it is recommended to use it after verification in your own environment, after all, daishen’s environment is still different from your own environment.

Performance related

-xx: -usebiasedlocking -xx: -usecounterdecay -xx :AutoBoxCacheMax=20000 -xx :+PerfDisableSharedMem (optional) -xx :+AlwaysPreTouch -Djava.security.egd=file:/dev/./urandom

Memory size dependence (JDK7)

-Xms4096m -Xmx4096m -Xmn2048m -XX:MaxDirectMemorySize=4096m -XX:PermSize=128m -XX:MaxPermSize=512m -XX:ReservedCodeCacheSize=240M

If using jdk8, replace -xx :PermSize=128m -xx :MaxPermSize=512m with -xx :MetaspaceSize=128m -xx :MaxMetaspaceSize=512m These two sets of parameters are to ensure safety, it is suggested to add.

CMS GC related

-XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:MaxTenuringThreshold=6 -XX:+ExplicitGCInvokesConcurrent -XX:+ParallelRefProcEnabled

GC log correlation

-Xloggc:/dev/shm/app-gc.log -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCDateStamps -XX:+PrintGCDetails

Exception Log Correlation

-XX:-OmitStackTraceInFastThrow -XX:ErrorFile=${LOGDIR}/hs_err_%p.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${LOGDIR}/

JMX related

– Dcom. Sun. Management. Jmxremote. Port = ${JMX_PORT} – Dcom. Sun. Management jmxremote – Djava. Rmi. Server hostname = 127.0.0.1 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false

reference

  • Java performance optimization guide 1.8 version, and vipSHOP actual combat
  • Escape analysis and TLAB and Java object allocation in Java
  • The Four Month Bug: JVM statistics cause garbage collection pauses

Hello, I’m looking at the mountains. Swim in the code, play to enjoy life. If this article is helpful to you, please like, bookmark, follow. Welcome to follow the public account “Mountain Hut”, discover a different world.

The image was published by G3GG0 on Pixabay