preface
You’re no stranger to JVM tuning, and I’m sure you’ve heard your friends say: In the interview, some interviewers will grasp the point of JVM tuning, will ask a lot of questions about THE JVM tuning, I have been confused ๐ต although the interviewer will take it as a focus of the interview, but most of the partners in the actual development process rarely optimize the JVM, So you don’t know much about JVM tuning. Today, LET’s talk about THE JVM in a nutshell and share my knowledge with you ๐
What is the JVM
Before we talk about JVM tuning, let’s look at what the JVM is ๐.
The JVM, short for Java Virtual Machine, is a specification for computing devices. The JVM is an imaginary computer that is implemented by emulating various computer functions on an actual computer.
With the introduction of Java language virtual machines, the Java language does not need to be recompiled when running on different platforms. The Java language uses the Java Virtual machine to mask platform-specific information, allowing Java language compilers to run unmodified on multiple platforms by generating object code (bytecode) that runs on the Java Virtual machine. (Above content from Baidu)
A Java virtual machine is essentially a program that, when launched on the command line, begins executing instructions stored in a bytecode file. The portability of the Java language is based on the Java virtual machine. You’ve probably heard the phrase: Java is a platform-independent programming language because of the Existence of the Java Virtual Machine, which knows the instruction length and other features of the underlying hardware platform, Also, Java source files can be compiled into bytecode files (.class files) that can be executed by the Java VIRTUAL machine, so any platform that has a Java VIRTUAL machine running on it, Bytecode files (.class files) compiled from Java source files can be run on the platform, which is called “compile once, run many times”.
So might be a little not understand, or rituals, tell you about my “obscene” : for example, we now need to keep a little duck, but our breeding environment change frequently (raised at home today, tomorrow can go to other places), because the duck is small, so we need to prepare his incubator, make it a comfortable life in the incubator. If we keep it at home, we use a normal incubator. If we change it to a colder place, then we need to change it to a thicker incubator. Duckling is the Java source file we wrote, and the incubator is the Java VIRTUAL machine. Different environments correspond to different platforms. No matter what kind of environment we want to raise duckling in, as long as we change the corresponding incubator, we can let the duckling grow up quickly and happily.
So what if we want to improve the ducklings’ quality of life? In fact, the solution is very simple, we can change the incubator, such as increasing the space, put a sink trough, put some cotton, etc., these methods can make the incubator “upgrade”, the process of upgrading the incubator is corresponding to the JVM tuning. Let’s get to the focus of the day — JVM tuning ๐
The JVM tuning
We develop a good system in the operation of the software before the online test or may encounter some problems, such as high CPU load, the request with a delay, or the waste collection every time more and long time use, frequency of garbage collection is more and more high, each garbage collection clean up garbage data less and less, and so on, these are the JVM problem, These problems affect the execution speed of the system software to a greater or lesser extent, so we need to tune the JVM. The ultimate goal of our tuning is to have an application that can carry more throughput with minimal hardware consumption. JVM tuning is a collection performance optimization for the garbage collector, enabling applications running on virtual machines to use less memory and latency for greater throughput. In other words, it is a better user experience and efficiency while running properly.
JVM tuning steps
For those of you who think about JVM tuning, the idea is daunting and you don’t know where to start. In fact, the steps of JVM tuning are very simple ๐
(1) Analyze GC logs and dump files to determine whether optimization is needed and determine the root cause of the problem; (2) determine the QUANTIzation objectives and JVM tuning parameters (JVM tuning parameters are adjusted based on historical JVM parameters); (3) Tune memory, latency, throughput and other indicators in sequence; (4) compare the differences before and after tuning. You need to constantly analyze and tweak the parameters until you find the right JVM parameter configuration. โค Find the most appropriate parameters, apply these parameters to all servers, and follow up.
To summarize the above steps, there are three steps (like putting an elephant in a refrigerator ๐) : first, analyze the log to see if it needs tuning; Secondly, confirm tuning objectives and tuning parameters; The final step is to test and track. This time the JVM tuning is not so tricky ๐
Some of the steps above require multiple iterations (such as tuning parameters and tracking performance after tuning). Here need to be aware of is that, when we tune in general began from meet the demand of application memory use, the next is to meet the requirements of the application of time delay, the last is to meet the requirements of the application throughput, we should follow this step to continuously optimize, every step is the basis of the next step, you must not do exactly the opposite ๐ฒ.
JVM parameters
In the above mentioned steps, the most important step is to adjust the JVM parameters, so we need to have a certain understanding of the JVM parameters, I will first talk about the JVM parameters related content ๐
The -xx parameter is known as an unstable parameter, and setting this parameter can easily lead to JVM performance differences, which can make the JVM extremely unstable. Setting these parameters properly will greatly improve the performance and stability of the JVM. This kind of unstable parameters can be understood as a double-edged sword, which can increase the power if used well, and may appear to hurt the enemy one hundred and lose ten thousand if used badly. Unstable parameters are mainly divided into three categories, namely Boolean parameter value, numeric parameter value and string parameter value. There are two types of Boolean parameter values: -xx :+ and -xx :-, where + indicates that the option is enabled. – indicates that the option is disabled. The format of the numeric type parameter is as follows: -xx:, to set a numeric type value, after which the unit can be added, for example, M or M for megabytes, k or K for kilobytes. The format of a string argument is the same as that of a number argument, except for the number that follows it. A string argument sets a string value, which is usually used to specify a file, path, or list of commands. For example, -xx :HeapDumpPath= XXX/XXX/XXX (file path).
Let’s look at some specific examples ๐
-Xms2g -Xmx2g -Xmn512M -Xss128K -XX:PermSize=128M -XX:MaxPermSize=128M -XX:NewRatio=4 -XX:SurivorRatio=4 -XX:MaxTenuringThreshold=1
-
-Xms2g: The initial heap size of THE JVM is 2 gb. The default for Xms is 1/64 of the physical memory but less than 1 GB.
-
-XMX2G: JVM maximum heap size is 2g, Xmx default is 1/4 of physical memory but less than 1G; Setting the values of -xms and -xmx to be the same prevents the JVM heap size from being resized after each garbage collection.
-
-Xmn512M: The size of the new generation in the heap is 512 MB
-
-Xss128K: The stack size of each thread is 128K
-
-xx :PermSize=128M: The initial size of the JVM persistent generation is 128M
-
-xx :MaxPermSize=128M: The maximum size of the JVM persistent generation is 128M
-
-xx :NewRatio=4: The ratio of new generation to old age of the JVM heap is 1:4
-
-xx :SurvivorRatio=4: The ratio between Cenozoic Surivor zone (there are two Surivor zones in Cenozoic era) and Eden zone is 2:4
-
-xx :MaxTenuringThreshold=1: Objects of the new generation enter the old age after several garbage collections (if they survive). If this parameter is set to 0, it means that objects of the new generation enter the old generation without entering the survivor zone after garbage collection
-XX:+UseParallelGC -XX:ParallelGCThread=4 -XX:+UseParallelOldGC -XX:MaxGCPauseMillis=100 -XX:+UseAdaptiveSizePolicy
- -xx :+UseParallelGC: Uses a parallel garbage collector, but only for the new generation, older generations still use a serial collector
- -xx :ParallelGCThread=4: Sets the number of concurrent garbage collector threads to 4, preferably the same as the number of processors
- -xx :+UseParalleOldGC: enables the old generation to use the parallel garbage collector. JDK1.6 supports the old generation to use the parallel garbage collector
- -xx :MaxGCPauseMillis=100: Sets the maximum time for each new generation of collector garbage collection. If this time cannot be met, the JVM automatically adjusts the size of the new generation area to meet this value
- -xx :+UseAdaptiveSizePolicy: After setting this value, the JVM automatically adjusts the size of the new generation and the corresponding ratio of the Surivor area to achieve the set minimum response time or collection frequency
-XX:UseConcMarkSweepGC -XX:+UseParNewGC -XX:CMSFullGCsBeforeCompaction=5 -XX:+UseCMSCompactAtFullCollection
- -xx :UseConcMarkSweepGC: Sets the age of the JVM heap to use the CMS concurrent collector. After setting this parameter, the -xx :NewRatio parameter is invalid, but the -xmn parameter is still valid
- -xx :UseParNewGC: sets the new generation to use the concurrent collector. After JDK1.5, the JVM will set this automatically based on the system
- – XX: CMSFullGCsBeforeCompaction = 5: set up 5 CMSGC to compression, the heap space after finishing
- – XX: + UseCMSCompactAtFullCollection: open the old s compression, may affect performance, but can eliminate the pile of debris
JVM tuning parameters
There are many parameters involved in the JVM, but not all parameters need to be modified during the tuning process. For how to tune the JVM, I have compiled the following tuning suggestions for you (mainly because of my limited experience, not much ๐) ๐
- For JVM heap Settings, you can generally limit the minimum and maximum values with -xms and -xmx. To prevent extra time for the garbage collector to shrink the heap between the minimum and maximum values, we usually set the minimum and maximum values to the same value.
- The heap memory of the young generation and the old generation will be allocated according to the default ratio (1:2), which can be adjusted by adjusting the ratio NewRadio between the two. In addition, other methods can be used to set the size. For example, for the young generation, the absolute size can be set by -xx :newSize -xx :MaxNewSize. Also, we usually set -xx :newSize -xx :MaxNewSize to the same size to prevent heap shrinkage of the younger generation.
- Young and old generation memory size is related to, like a seesaw relationship between (a memory becomes gao will lead to another memory become low), so in setting up the memory size need to be cautious, we can apply for a period of time through the observation, the application in the peak old generation will account for how much memory, Without affecting the Full GC, young generation memory can be increased as required, such as 1:1 ratio. One thing to be careful about is that when we adjust the memory size, we want to make sure that the old generation has enough room to grow.
- On servers with high configuration (such as multi-core, large memory), we can choose the parallel collection algorithm for the aged generation: -xx :+UseParallelOldGC.
- By default, each thread opens a 1M stack for stack frames, call parameters, local variables, etc. For most applications, this is too much space, so 256K is usually sufficient when setting thread stack space.
- If the application is running times Java. Lang. OutOfMemoryError: Direct buffer memory exception, we can increase – XX: MaxDirectMemorySize value, increase Direct memory.
- If we still don’t know which parameter to adjust, we can choose to use an analysis tool (such as GCViewer) to help us. Using the tuning tool, we can intuitively analyze the advantages to be adjusted. (This trick can be called a trick, ha ha ha ๐)
Some tips on JVM tuning
Finally, a few tips on JVM tuning: The average project does not need to tune the JVM, and even for high-concurrency or high-volume services or software, tuning the JVM is not that important. Because the JVM itself is for the low latency and high concurrent throughput of service design and optimization, we really little need to change anything, so even met need tuning, we should also pay attention to be tuned to the application itself (if rushed to tuning of the JVM, perhaps causes more problems). To put it more bluntly, some projects may run just fine even if the OPTIMIZED parameters of the JVM are removed (and there may be problems in extreme cases).
And I don’t know why many companies tend to focus on the JVM and ask a lot of questions about it when interviewing JAVA programmers, which I feel is a bit of a waste of time. And don’t know if your friend have encountered this kind of colleagues, they stab to solve a problem like a pole to the bottom, encounter problems should first put forward is the JVM BUG result in abnormal, meet high latency circumstance will say GC algorithm has a problem, they will even consider to replace the GC algorithm (don’t know is which come of confidence ๐), To be honest, even if the JVM is drained of oil, it is better to optimize the business logic.
summary
My experience is limited, some places may not be particularly in place, if you think of any questions when reading, welcome to leave a message in the comments section, we will discuss one by one ๐
Please take a thumbs up and a follow (โฟโกโฟโก) for this article ~ a crab (โ’โก’โ)
If there are mistakes in the article, welcome to comment correction; If you have a better, more unique understanding, you are welcome to leave your valuable ideas in the comments area.
Love what you love, do what you do, listen to your heart and ask nothing