preface

The title is not wrong, really let me write a bug!

When I first received this request, MY heart was not stirred, even a little excited. This is my specialty; Finally can open and aboveboard write bug 🙄.

Let’s take a look at the details of what to do, in fact, the main is to make some low load server extra consumption of memory, CPU and other resources (as for the background will not say), so that its load can be increased.

Review of JVM memory allocation

With a quick flick of the shuttle, I wrote the code, which looks something like this:

After writing it, I wondered if the MEM object in the code would be recycled immediately after the method was executed. I’m sure there are a few people who think it’s just after the method executes.

I also serious investigation, asked some friends; Sure enough, there are some that say recycle after the method completes execution.

So what are the facts? I did an experiment.

I started the application with the following startup parameters.

java -Djava.rmi.server.hostname=10.xx.xx.xx 
-Djava.security.policy=jstatd.all.policy 
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.ssl=false 
-Dcom.sun.management.jmxremote.port=8888  
-Xms4g -Xmx4g  -jar bug-0.0.1-SNAPSHOT.jar
Copy the code

This allows me to remotely connect to the application through a JMX port to observe memory and GC.


If the meM object is recycled after the method is executed, when I allocate 250M memory; Memory will have a distinct curve and GC will execute.


Now look at the memory curve.

You do see a significant increase, but then you don’t get it back immediately, you stay at the same level. And the GC on the left doesn’t react at all.

The same is true for viewing memory layouts using jstat.

Neither YGC nor FGC, but Eden’s usage has increased since 250M of memory is allocated.

So how do you recycle?

I re-allocated two 250MB and then observed the memory curve.

When the third 250M is found, Eden area reaches 98.83%, so it is necessary to reclaim Eden area during redistribution, resulting in YGC.

The memory curve also went down.

The whole conversion process is shown as follows:

Since the heap is initialized with 4G memory, the Eden area calculated is approximately 1092M memory.

Add in about 20% of the memory consumed by an application starting up Spring and so on, so allocating 250M memory three times will result in YGC.

Let’s go back to the question:

Mem objects are not recycled after the method is executed, so when.

Just remember that objects need to be collected by the garbage collector; Whether the object is a local variable or a global variable.

It is also found from the previous experiment that the MEM object created by us will be recycled only when the Eden space is insufficient to generate YGC.

But there is a hidden condition: the object is local. If the object is a global variable, it still cannot be reclaimed.

This is also known as unreachable objects, so that unreachable objects are considered objects that need to be collected when GC occurs.

For a second, why do some people think that local variables are recycled after a method is executed?

I think this is a bit of a mix-up, but it’s actually the stack frame that gets recycled after the method completes.

The immediate result is that the mem object is not referenced. The absence of a reference does not mean that it will be collected immediately, as the above mentioned need to generate a GC to collect.

So the reachability analysis algorithm used for unreachable objects mentioned above is used to indicate which objects need to be reclaimed.

Objects are considered unreachable when they are not referenced.

Here’s a GIF that’s a little clearer:

When the method completes, the MEM Object is equivalent to Object 5 in the figure, so it is reclaimed during GC.

Allocate objects in Eden area first

In fact, it can be seen from the above example that objects are preferentially allocated in Eden area in the new generation, but there is a premise that objects cannot be too large.

I’ve written about this before:

Big object goes straight to the old age

Large objects are allocated directly to the old age (the size can be configured by parameter).


When I directly allocated 1000M of memory, the Eden area could not be directly installed, so THE allocation was changed to the old age.

It can be seen that the Eden area has hardly changed, but it has increased by 37% in the old age. According to the previous calculation of memory 2730M in the old age, it is almost 1000M memory.

Linux Memory Viewing

Back to the requirements I need to complete this time: increase server memory and CPU consumption.

The CPU is fine, it has its own usage, and each object created consumes some CPU.

It’s mainly memory, so let’s look at the memory before we start this application.

It only used about three gigabytes of memory.

After launching the application, it only consumes about 600MB of memory.

I need to allocate some memory to meet the demand, but it’s a little tricky here.

You can’t allocate memory all the time, so the CPU load is too high, and the memory usage is not very high due to GC collection.

So I need a small allocation, so that most objects in the new generation, in order not to be recycled need to be 80 or 90 percent.

At the same time, we also need to allocate some large objects to the old age, and also keep the old age usage at 80 or 90 percent.

This will make the most of the 4G heap memory.

So I did the following:

  • First allocate some small objects in the Cenozoic (800M) to keep the Cenozoic at 90%
  • And then it’s distributed* in old age (100%- 28% used); Is the 2730 * 60% = 1638 mLet the old age is also around 90%.

The effect is as above.

The main thing is that not a single GC has happened and that has served my purpose.

The final memory consumption was around 3.5GB.

conclusion

Although the requirements are odd, it is not easy to accurately control the MEMORY allocation of the JVM.

Need to have a certain understanding of its memory layout, recycling, the process of writing this Bug has indeed deepened the impression, if it is helpful to you, please do not mean your likes and shares.

Your likes and shares are the biggest support for me