preface

Welcome to our GitHub repository Star: github.com/bin39232820… The best time to plant a tree was ten years ago, followed by now. I know many people don’t play QQ anymore, but for a moment of nostalgia, welcome to join the six-vein Shenjian Java rookie learning group, group chat number: 549684836 encourage everyone to write blog on the road of technology

omg

Previous chapters

  • The G1 garbage collector

review

In the above article, you can actually understand G1’s dynamic memory management strategy. It will dynamically allocate Regiuon to the new generation, Eden,Survivor, old generation and big object according to the situation, but the new generation and old generation have a maximum proportion respectively, and then when the Eden of the new generation is full, the garbage collection of the new generation will be triggered.

The new generation of garbage collection still adopts the replication algorithm, but it will consider the preset GC pause time to ensure that the pause time of garbage collection is not difficult to exceed the set time, so it will select some regions for garbage collection.

Then, as mentioned earlier, objects will enter the old age if they survive a certain number of GC draws in the new generation or trigger dynamic age rules

Large objects, on the other hand, enter a separate Regin and no longer enter the old age

So in fact, in G1, there will still be a new generation of objects that will go into the old age for various reasons

When does G1 trigger Cenozoic + old age mixed garbage collection?

The G1 has a parameter is – XX: InitiatingHeapOccupancyPercent its default value is 45%

If the old generation occupies 45% of the Region in the heap, the mixed reclamation phase will be triggered

G1 Garbage collection process

An initial tag operation is triggered, which needs to Stop the world, but this process is quick

As shown in the figure below, first stop the running of the system program, then scan the local variables representing GC Roots in the memory of each thread stack, and Roots representing static variables in the method area, and mark their direct reference objects.

Next comes the concurrent marking phase, which allows the system program to continue running while GC Root tracing, as shown below

This concurrent tagging phase is still time consuming because all live objects need to be traced

However, this stage can be concurrent with the system program, so the impact on the system program is not too big

Furthermore, the JVM keeps a record of the concurrent marking phase objects, such as which objects are newly created, which objects are unreferenced, and so on

The next stage is the final tag stage, which also enters Stop the world. The system program is not allowed to run, but records object modifications based on concurrent tags, and finally marks which objects survive, as shown in the figure below

The final phase is the mixed collection phase, which calculates the number of live objects in each Region in the old era, the percentage of live objects, and the expected performance and efficiency of garbage collection.

The system program is then stopped and the collection is done as quickly as possible, with partial regions selected because the pause time for garbage collection must be within the range we specify.

For example, in the old days, 1000 regions are full, but due to the time set, only 200ms can be stopped. Instead of only 800 regions can be reclaimed, only 800 regions can be reclaimed, and the GC time can be controlled within the specified range, as shown in the following figure

Case background introduction

This is an online education platform with millions of registered users. The main target users are children from several years old to teenagers. There are about millions of registered users and hundreds of thousands of daily active users.

In fact, the business process of the system is not complicated, and we can eliminate some low-frequency behaviors such as selecting courses, arranging courses and browsing course details.

Why? Because it’s not an e-commerce platform, it doesn’t mean that everyone goes in and looks at the course details, so the general business process is that someone comes in and looks at the course, thinks about it for a while, and then buys the course. So what’s the high frequency behavior? I thought about it. It should be class

That means kids are in school during the day, usually around 8 or 9 at night, which is when the platform is most active, and on weekends,

Therefore, two or three hours in the evening will be the peak period of the platform, and there is almost no traffic during the day. Perhaps 90% of the traffic is read at night, as shown in the picture below

System core business process

So let’s figure out, what are the functions that children use most frequently in class for such a system

In fact, it is very simple, now if you have children at home, usually have a certain understanding of some online education apps, you should know that now online apps will be mainly interactive links

To give you an example, for example, for five or six year old children of kindergarten English class, do you think it will be the same as before, mechanically read after

Certainly not. There is a strong emphasis now on teaching in happy and enjoyable games, so that children can have fun learning about subjects like English and math

So when hundreds of thousands of users are using the system during the peak hours of the evening, the core business process is a lot of game interaction

That is to say, the interactive feature of the game will certainly bear the user’s high frequency of clicks, a lot of interactive clicks

For example, when completing any task, we must click a lot of buttons and interact frequently. Then the system background needs to receive a large number of interaction requests and record the results of user interaction.

The system has to keep track of how many tasks the user has completed, how many they have done right, and how many they have done wrong.

Operating pressure of the system

Let’s start by analyzing a stress on memory usage at runtime

The core point is to figure out how many requests there are per second, how many objects are associated with each request, how much memory is used, and how long each request takes to process during the peak two or three hours in the evening.

Let’s first analyze how many requests per second are generated during peak evening hours when hundreds of thousands of users are online at the same time.

We can make a rough estimate. For example, during the 3-hour peak period in the evening, there are 600,000 active users. The average user will use about 1 hour to attend the class, and will conduct 60 interactions within an hour

Therefore, 20W active users need a large number of interactive operations, so it can be roughly regarded as one interactive operation per minute, or 60 interactive operations within an hour

So 200,000 users will do 12 million interactions in an hour, which is about 3,000 interactions per second, which is a reasonable number

So it needs to handle 3000 concurrent requests per second. According to experience, the average core system needs to deploy 5 4-core 8G machines to withstand 600 requests. This pressure is acceptable and generally will not cause downtime problems.

So how many objects are generated per request?

An interaction request will not have too complex objects, it is mainly to record some user interaction process, may be associated with some integral things

So just to give you a rough estimate of how many objects will be created in one interactive request, let’s say 5KB and then 600 requests per second will take up about 3MB of memory

Default memory layout for G1 garbage collection

Next, let’s look at the default memory layout of the G1 garbage collector. We deploy the system on a 4-core, 8-GIGAByte machine, and each machine has 600 requests per second that take up about 3Mb of memory.

So suppose we allocate 4G heap memory to the JVM on the machine, with the default initial 5% for the new generation and 60% for the maximum, 1MB stack memory for each Java thread and 256MB metadata area memory, and the JVM parameters are as follows

The -xx :G1NewSizePercent parameter is used to set the initial proportion of the new generation. The default value is 5%

The -xx :G1MaxNewSizePercent parameter is used to set the maximum size of the new generation. It is not required to maintain the default 60%

In this case, the size of each Region is calculated by dividing it by 2048. At this point, the size of each Region is 2MB. At the beginning, 5% of the regions are in the new generation, so it can be considered that the new generation has only 100 regions and 200MB memory space, as shown in the following figure.

Set the GC pause time

One crucial parameter in the G1 garbage collector that affects GC performance is -xx :MaxGCPauseMills, which defaults to 200 milliseconds

Stop the world for no more than 200ms every time we trigger a GC to prevent the system from being stuck for a long time.

This parameter we can keep a default value, continue to analyze see, do not jump to conclusions

How long does it take to trigger a new generation GC?

There is a problem, that is, after the system runs, it will continuously allocate objects in the Eden area of the new generation. According to the previous calculation, it will allocate objects of 3MB per second, as shown in the figure below

When will Eden run out of territory?

The -xx :G1MAXNEWSIZE parameter specifies the maximum heap size for the new generation

Do you have to allocate more regions to the new generation as the system runs until the new generation occupies 60% of the Region before GC?

That’s certainly not how the G1 works

Let’s assume that it takes 200ms for G1 to reclaim 300Region

Chances are, when the system runs, G1 will look something like this

First, as the system runs, 3MB objects are created every second, filling up 100 regions in about a minute, as shown in the figure below

At this point, G1 will probably feel that if I trigger GC now, it will only take me a few tens of ms to reclaim a mere 200MB, and at most it will stop the system a few tens of ms, far from the 200Ms that my owner set.

If it’s gc now, is it too frequent to gc every minute? It doesn’t seem necessary

It would be better to add some regions to the new generation and then let the system continue to run and allocate objects to the new generation regions so that the new generation GC is not triggered too often, as shown in the figure below

Then the system continues until all 300 regions are occupied. At this point, it takes about 200ms to reclaim 300 regions by calculation, and a new generation GC may be triggered at this time

G1 is very flexible and will assign new generations more regions at any given time

Then, when it feels good enough, it will trigger the new generation GC, ensuring that the system pauses during the new generation GC are within your preset range

How to optimize the New generation

The -xx :MaxGCPauseMills parameter is optimized

If this parameter is set to a small value, then pauses per GC are short but frequent

If this parameter is set too high the pause time will be very long,

So how to set this parameter, need to combine tools to test, to achieve a reasonable value

How to optimize in the old days

-xx :MaxGCPauseMills

You can imagine that if this parameter is large, then the Survivor region will not hold so many objects after the new generation of GC, and these objects will enter the old age

Or because the dynamic age judgment has entered the old age, so it is better to set this parameter

At the end

In fact, it is simply said G1, the back of the specific dry goods

I have a goal to write two or three articles a week. I hope I can keep it up for a year. I hope you can give me more suggestions so that I can learn more and make progress together.

Daily for praise

Ok, everybody, that’s all for this article, you can see people here, they are real fans.

Creation is not easy, your support and recognition, is the biggest motivation for my creation, we will see in the next article

Six pulse excalibur | article “original” if there are any errors in this blog, please give criticisms, be obliged!