JVM core parameters
-Xms: size of Java heap memory
-Xmx: maximum size of Java heap memory
-Xmn: the size of the new generation in the Java heap memory. After deducting the new generation, the rest is the memory size of the old age
-20: Permsize: permanent generation size
-20: Maxpermsize: maximum permanent size
-Xss: stack memory size per thread
-Xms and - Xmx are used to set the initial size of Java heap memory and the maximum size allowed to expand to, respectively.
These parameters are usually set to exactly the same size. These two parameters are used to limit the total size of Java heap memory.
-Xmn, this parameter is also very common. It is used to set the size of the new generation in the Java heap memory, and then the remaining memory after deducting the size of the new generation is the memory size of the old age.
-20: Permsize and - XX:MaxPermSize respectively limit the size of the permanent generation and the maximum size of the permanent generation. Usually, these two values are set to the same value.
For JDK versions after 1.8, these two parameters are replaced with - XX:MetaspaceSize and - XX:MaxMetaspaceSize. However, we should at least know that these two parameters limit the size of the permanent generation.
-Xss, this parameter limits the stack memory size of each thread.
As we all know, each thread has its own virtual machine stack. Each time a method is executed, the stack frame of the method will be pressed into the thread stack. After the method is executed, the stack frame will be out of the thread stack.
Let's set the JVM parameters in combination with the business
We use a payment system with daily million transactions as the background to analyze how to reasonably set the heap memory size of the JVM according to the system traffic when we deploy a system online.
-Let's talk about the core process of the payment system first
Through the steps of adding the icon number and serial number, you can clearly know this process First, the user submits a request to pay an order in our mall system, and then the mall system submits the request to the payment system, and the payment system will generate a payment order. At this time, the order status may be "to be paid". Then the payment system directs the user to jump to the payment page and select a payment method Then the user initiates the actual payment request, the payment system transfers the actual payment request to the third party payment channel, such as WeChat or Alipay, they will process the payment request to transfer funds. If WeChat or Alipay processes the payment, it will return the payment result to the payment system, and the payment system can update its local payment order status to "completed". Of course, a complete payment system also contains many things. For example, it is also responsible for reconciliation and fund clearing with cooperative merchants. The payment system must include various functional modules such as application management, account management, channel management, payment transaction, reconciliation management, clearing management and settlement management. However, we can focus on the core payment process here.
-Where is the pressure of the daily million trading system
Next, let's consider where the pressure of a payment system with millions of transactions per day is concentrated? For example, the core payment process above, our system has millions of transactions every day. Generally up to one million transactions, or it is the largest Internet company in China, or it is a general-purpose third-party payment platform to connect with all kinds of transactions APP Payment transactions. In fact, as you can see from the above figure, the core link in the above business process is that when a user initiates a payment request, a payment order will be generated. This payment order needs to be recorded clearly, such as who initiated the payment? Payment for which goods? Through which channel? And the time to initiate payment? Wait, information like that. If the daily million transactions, then you can imagine, in our JVM From the point of view, every day JVM Create millions of payment order objects in. Think about it carefully. Is that the case? As shown in the following figure: in fact, the pressure of our payment system has many aspects, including high concurrent access, high-performance processing requests, a large number of payment order data need to be stored, and other technical difficulties. But put aside these things at the system architecture level, just JVM On the one hand, the biggest pressure on our payment system is every day JVM One million payment orders will be frequently created and destroyed in memory, so this involves a core problem. How many machines do we need to deploy in our payment system? How much memory space does each machine need? Started on each machine JVM How much heap memory needs to be allocated? to JVM How much memory space can you guarantee that you can support the creation of so many payment orders in memory without causing a direct crash due to insufficient memory? This is the core problem we want to consider in this paper.
-How many payment orders does the payment system need to process per second
To solve one of the core parameters of the online system, that is JVM For the reasonable setting of heap memory size, the first thing we need to calculate is how many payment orders our system has to process per second. Assuming 1 million payment orders per day, the general user transaction behavior will occur at the peak of each day, such as noon or evening. Assuming that the peak period of each day is about a few hours, and 1 million is evenly allocated to a few hours, it is about 100 orders per second. Let's calculate by 100 orders per second. Suppose that our payment system deploys three machines, and each machine actually processes about 30 orders per second. Let's look at the following figure, which can reflect the order processing pressure of the payment system every second.
-How long does each payment order take
The next question we must understand is how long each payment order will take to be processed? If the user initiates a payment request, the payment needs to be made in JVM Create a payment order object in, fill in the data, and then write the payment order into the database. It may also handle some other things. Let's assume that the processing of a payment request includes the creation of a payment order, which takes about 1 second. So, in general, a flow model that can appear in your mind should be that each machine receives 30 requests for payment orders in one second, and then JVM In the new generation, 30 payment order objects were created and written into the database After 1 second, the 30 payment orders are processed, and then the reference to these payment order objects is recycled. These orders are JVM The new generation of is the garbage object that no one references. Then there are 30 payment orders in the next second, and repeat this step.
-How much memory space does each payment order need
Next, let's calculate how much memory space each payment order object needs? There is a thinking problem in the previous article, which has taught you how to calculate this. In fact, without considering anything else, you can calculate it directly according to the type of instance variable in the payment order class. For example, the payment order class is as follows. You just need to remember one Integer The variable data of type is 4 bytes, Long The variable data of type is 8 bytes, and how many bytes do other types of variable data occupy.
Generally speaking, for example, the core class of payment order, you calculate by 20 instance variables, and generally an object looks like a few hundred bytes. Let's make it a little bigger. Even if a payment order object occupies 500 bytes of memory space, less than 1 kb.
-Memory usage of payment requests initiated per second
As mentioned earlier, assuming that there are three machines that process 30 payment order requests per second, we all know that there must be local variables in the method referencing these payment orders within one second, as shown in the following figure:
The memory space occupied by 30 payment orders is about 30 * 500 byte = 15000 Bytes, about 15 kb nothing more. It's actually very, very small.
-Let the payment system run and analyze it
Now that we have analyzed the data of the key links in the operation of the whole system, you can think about it in your mind. 30 payment requests per second and 30 payment order objects are created, which will occupy kb Level of memory space Then one second later, these 30 objects are not referenced and become garbage in the new generation. When the request comes in the next second, our system continues to create payment order objects, and keeps putting 30 payment orders in the new generation, and then the objects in the new generation will continue to accumulate and increase. Until one moment, it was found that there may be hundreds of thousands of objects in the Cenozoic, which occupied hundreds of objects at this time MB The space of the new generation may be almost full. Then it will trigger Minor GC，The garbage objects in the new generation are recycled to free up memory space, and then continue to allocate new objects in memory. This is the operation model of the business system.
-Estimate the memory consumption of the complete payment system
The previous analysis is all based on a payment order object in a core business process. In fact, it is only a small part. A real payment system running online will certainly create a large number of other objects per second, but we can roughly estimate how much memory the whole payment system will occupy per second by combining this access pressure and the memory occupation of the core objects. In fact, if you want to estimate, you can expand the previous calculation results by 10 times~20 Times. In other words, in addition to creating payment order objects in memory, dozens of other objects will be created every second. Then the memory space occupied by the objects referenced by the local variables in the stack memory created every second is about several hundred KB~1MB between. Then continue to create a new request next second, about 1 MB The object is placed in the new generation, then becomes garbage, and then the next second. After multiple cycles, if there is too much garbage in the new generation, it will be triggered Minor GC Recycle the garbage. This is the outline of a complete system JVM Level memory usage model.
-How should the JVM heap memory of the payment system be set
In fact, after analyzing the core business process of the payment system, you will fully know that when such an online system is deployed on each machine, JVM How should the heap memory be set. In fact, generally speaking, the common machine configuration of this online business system is 2-core 4-core G，Or 4-core 8 G. If we use 2-core 4 G It is still a little compact because the machine has 4 G Memory, but the machine itself also needs some memory space. Finally, your JVM The maximum number of processes is 2 G Memory. Then this 2 G It also has to be allocated to several areas of method area, stack memory and heap memory, so the heap memory may be at most 1 G More memory space. Then the heap memory is also divided into the new generation and the old generation. In your old age, you always need to place some long-lived objects of the system. You have to give hundreds of them anyway MB Memory space, Then the Cenozoic may be hundreds MB I'm out of memory. In this case, you can see that the core business processes mentioned above are only analyzed for a payment order object, but in fact, if they are expanded by 10 times~20 After doubling the estimate for the complete system, we see that it will occupy about 1 per second MB Left and right memory space. So if you have hundreds of new generations MB Will the memory space of the new generation be full after running for hundreds of seconds? Does it have to be triggered at this time Minor GC What happened? In fact, if it is triggered so frequently Minor GC，It will affect the performance stability of the online system. The specific reasons will be discussed later. The first thing you should understand here is that it is triggered frequently GC It must not be a good thing. So you can consider using 4-core 8-core G The machine to deploy the payment system, then your JVM The process can give at least 4 G The memory of the new generation can be allocated to at least 2 G In this way, the memory space can be increased by 1 per second in the new generation MB About, but it takes nearly half an hour to an hour for the new generation to trigger Minor GC，This greatly reduces GC Frequency of. For example: the machine uses 4 cores and 8 cores G，then-Xms and-Xmx Set to 3 G，Give the whole heap memory 3 G Memory space,-Xmn Set to 2 G，To the Cenozoic 2 G Memory space. Moreover, assuming that your business volume is larger, you can consider deploying not only 3 machines, but also 5 machines or 10 machines horizontally, so that each machine can process fewer requests JVM Less pressure.
Starting from a payment system case, this paper takes you a little to calculate how many orders each machine needs to process per second, how long it takes to process each order, and what will happen to each second when the system deploys three machines under the pressure of daily million transactions JVM How much memory space does it occupy? According to this horizontal expansion, it is estimated how much memory space the whole system needs to occupy per second. Then, according to the above data model, calculate how much memory space your new generation will have under different machine configurations, and then how often it will be triggered under different sizes of the new generation Minor GC. To avoid frequent GC，So what kind of machine configuration should be selected and how many machines should be deployed JVM The memory space of heap memory and the memory space of the new generation. According to this set of configuration, you can calculate the operation model of the whole system. How many objects are created in the new generation every second, and then become garbage after one second. About how long the system runs, the new generation will trigger once GC，How high is the frequency.