Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to understand JVM and garbage collection

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly explains "how to understand JVM and garbage collection". The content of the article is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought to study and learn "how to understand JVM and garbage collection".

The development of JVM

Just as we use tripartite libraries, the same functions have different implementations. The same is true of JVM, the first JVM is the Classic VM,JDK1.2 of Sun, JVM used Classic VM before, and then it was gradually replaced by HotSpot, as we all know, until JDK1.4,Classic VM was completely abandoned.

HotSpot should be the most widely used virtual machine at present (confidence point, should be removed), and it is also the virtual machine that comes with OpenJDK. But you may not know that HotSpot was not originally developed by Sun, but was designed and implemented by a small company, and was not originally designed for the Java language. Sun saw the advantage of the virtual machine in JIT, so it acquired the company and acquired HotSpot VM.

Runtime memory area

Maybe you've experienced what it's like to be tortured by the soul. if OOM (Out Of Memory) occurs online, how to investigate? What would you do if you were asked to tune the running parameters of a JVM?

Unlike C++, which can dominate memory by itself and play the role of God and the lowest labor at the same time, in Java we hand over memory management to JVM, if we don't understand the specific runtime memory distribution and the principle of garbage collection, then when the problem really arises, we probably won't be able to find it. This is also the need to have an in-depth understanding of JVM.

At run time, Java divides the memory into the following areas for management: heap, method area, virtual machine stack, local method stack, and program counters.

Heap

The Java Heap is the largest block of memory managed by JVM. Almost all objects instantiated using the new keyword in our normal development will allocate memory in the heap, and all threads can share the objects allocated on the heap.

Heap is also the main area of JVM garbage collection. Because of the generation mechanism of garbage collection, the heap can also be divided into more detailed Cenozoic and old age. GC will be discussed in more detail later.

Then why almost? JVM's own specification stipulates that all objects allocate memory on the heap, but with the maturity of JIT (Just In Time) compiler and escape analysis technology, it becomes less absolute for all objects to allocate memory on the heap.

JIT compiler

I don't know if you've heard of it, but the law of 28 also applies in our program, that is, 20% of the code takes up 80% of the resources in the system. In the code we write, there may be some hot code that is called frequently. In addition to the code that is called frequently, the loop body that is executed many times is also considered hot code.

At this point, the JIT compiler will optimize this part of the code, compile it into Machine Code, and make some corresponding optimizations. Unfamiliar students may say, isn't all our code compiled into bytecode? Why is it compiled into Machine Code again?

Because the bytecode is only an intermediate state, the real run is that JVM translates the bytecode into Machine Code one by one, just like the interpreted language, and this Machine Code is the instruction that the operating system can recognize and run directly. On the other hand, JIT will save the Machine Code corresponding to the compiled hot code, and the process of compiling from bytecode to Machine Code will be saved when downloading and calling, and the efficiency will be improved naturally.

Escape analysis

As we just mentioned, almost all objects in Java allocate space on the heap, and the memory space in the heap is shared by all threads, so synchronization needs to be considered in multithreading. What if this variable is a local variable and will only be accessed in a function?

This kind of local variable is a non-escaping variable, and what if this variable can be accessed elsewhere? This indicates that this variable escapes from the current scope. Through escape analysis, we can know which variables have not escaped from the current scope, then the object memory can be allocated on the stack. With the end of the call, as the thread continues to execute, the stack space is reclaimed, and the memory allocated by this local variable is also reclaimed.

Method area

The method area stores data such as loaded Class information, constants, static variables, and compiled results of JIT. Like the heap, the method area is a memory area shared by all threads. But unlike the heap, the garbage collection effort of this piece can be said to be much smaller compared to the GC strength of the heap, but there is still a constant GC.

Virtual machine stack

The virtual machine stack is thread-private, so it is thread-safe and does not need to be synchronized under multithreading. When each method is executed, a stack frame is created in the virtual machine stack in the current thread, and the process from the call to the end of each method corresponds to the process of entering and unloading the stack frame in the virtual machine stack. Naturally, what should be stored in the stack frame are the local variables of the method, the Operand stack, the dynamic link, and the corresponding return information.

Do not know that you have encountered when writing recursion in a method, because the exit condition has not been met, causing the program to fall into an infinite loop, and then you will see that the program throws a StackOverflow error. The corresponding stack is the Operand stack mentioned above.

Of course, when there is enough memory, if there is not enough memory, OutOfMemory will be thrown directly, that is, OOM.

Local method stack

The function of the local method stack is similar to that of the virtual machine stack, except that the virtual machine stack serves the Java methods in JVM, while the local method stack serves the methods of Native.

GC

In fact, the area in the heap can also be divided into the Cenozoic era and the old age, and then it can be divided into Eden, From Survivor and To Survivor. The first object instance allocated will go to the Eden area, which is generally the largest in the Cenozoic era, with a ratio of 8:1 to From Survivor, which can be changed by the JVM parameter. And when the assigned object entity is very large, it will go directly into the old age.

The reason for a more detailed memory partition of the heap is to make garbage collection more efficient.

Garbage identification mechanism

So how does JVM determine which objects are "garbage" that need to be recycled? We need to see how JVM determines which memory needs to be reclaimed.

Reference count

The idea is to add a reference counter to each object, and every time another object references the object, the value of the reference counter is + 1. If the reference count of an object is 0, no object references it.

At first glance, there is no problem, so why didn't Java adopt this?

Imagine this scenario where two objects O1 and O2 are defined in a function, and then O1 refers to O2Magol O1 and O1, so that the reference counter for both objects is not zero, but in fact these two objects will never be accessed again.

So we need another solution to solve this problem.

Accessibility analysis

Reachability analysis can be understood as the traversal of a tree, the root node is an object, and its child node is the object that references the current object. If you start traversing from the root node, if you find that the traversal from all the root nodes has been completed, but there are still objects that have not been accessed, then these objects are unavailable and memory needs to be reclaimed.

These root nodes have a name called GC Roots. Which resources can be used as GC Roots?

The object referenced by the local variable in the stack frame

The object referenced by the class static property in the method area

The object referenced by a constant in the method area

Objects referenced by the local method stack

As we just talked about, in reference counting, if the value of its reference counter is 0, the occupied memory will be reclaimed. In reachability analysis, if there is no object without any reference, it will not necessarily be recycled.

Garbage collection algorithm

After talking about how JVM determines whether an object needs to be recycled, let's talk about how JVM does it.

Mark-clear

As the name implies, the process is divided into two stages, namely marking and clearing. First, mark all the objects that need to be recycled, and then uniformly recycle the marked objects. Because of the limitations of this algorithm, the first two processes of marking and clearing are inefficient, and this way of cleaning will produce a lot of memory fragmentation. What does that mean?

That is, although there seems to be enough remaining memory space on the whole, they are all scattered in a very small piece of memory. If you need to request space for a large object at this point, even if the overall memory space is sufficient, but JVM cannot find such a large piece of contiguous memory space, it will cause a GC to be triggered.

Copy

The general idea is to divide the existing memory space into two halves An and B, and the memory of all new objects is allocated in A, and then when A runs out, it begins to judge the survival of objects and copy the surviving objects in A to B. then reclaim the memory space in An at once.

In this way, there is no problem of using mark-to-clean memory fragments. However, it still has its own shortcomings. That is at the cost of halving the memory space, which in some cases is actually very high.

The Cenozoic generation of the heap is the replication algorithm used. As I just mentioned, the new generation is divided into Eden, From Survivor, and To Survivor, and since almost all new objects allocate memory here, the Eden area is much larger than the Survivor area. Therefore, the Eden and Survivor regions do not need to allocate memory according to the 1:1 default of the replication algorithm.

The default ratio of Eden to Survivor in HotSpot is 8:1, which means that only 10% of the space will be wasted.

You may find a problem when you see this.

Since your Eden area is so much larger than the Survivor area, what if the size of the surviving objects after a GC is larger than the total size of the Survivor area?

Indeed, in the new generation of GC, the worst-case scenario is that all objects in the Eden area are alive, so what do you do with this JVM? A concept called memory allocation guarantee needs to be introduced here.

When this happens, the new generation needs the memory space of the old age as a guarantee to store the objects that cannot be stored in Survivor directly into the old era.

Marking-finishing

Tagging-the process of demarcating its GC is the same as tagging-except that it moves all living objects to the same side, so that it doesn't leave a lot of memory fragmentation like tag-defragmentation.

Generational collection

This is also the current mainstream virtual machine algorithm, in fact, according to the characteristics of different memory areas, the use of different algorithms mentioned above.

For example, the feature of the new generation is that most objects need to be recycled, and only a few objects will survive. So the new generation generally uses the replication algorithm.

In the old era, it belongs to the memory space with high survival rate of objects, so mark-clear and mark-collate algorithms are used for garbage collection.

Garbage collector new generation collector

After talking about the garbage collection algorithm, we need to know more about the specific landing of GC, that is, the practical application of the above algorithm.

Serial

Serial uses a garbage collector that replicates algorithms and operates in a single thread. That is, when Serial does garbage collection, it must suspend all other threads' work until the garbage collection is complete, an action called STW (Stop The World). The GC in Golang will also have STW, and all running Goroutine will be paused during the preparation of its marking phase.

And this pause action is invisible to the user, the user may only know that a request has been executed for a long time, and it is difficult to hook up with GC without experience.

But in some ways, if your system only has a single core, then Serial will not have the overhead of thread-to-thread interaction, which can improve the efficiency of GC. This is why Serial is still the default new generation collector in Client mode.

ParNew

The only difference between ParNew and Serial is that ParNew is multithreaded while Serial is single-threaded. In addition, it uses exactly the same garbage collection algorithm and collection behavior.

If the collector is in a single-core environment, its performance may be worse than that of Serial, because a single core cannot take advantage of multithreading. In a multicore environment, the default number of threads is the same as the number of CPU.

Parallel Scavenge

Parallel Scavenge is a multithreaded collector and the default garbage collector in server mode. The above two collectors focus on how to reduce STW time, while Parallel Scavenge focuses more on system throughput.

For example, if JVM has been running for 100 minutes and GC has been running for 1 minute, then the throughput of the system is (100-1) / 100 = 99%.

Throughput and short pause time focus on different points, which need to be judged according to their own actual situation.

High throughput

The shorter the total time of GC, the higher the throughput of the system. In other words, high throughput means that the STW time may be a little more than the normal time, which is more suitable for the background system where there is not too much interaction, because the real-time requirements are not very high, you can complete the task efficiently.

Short pause time

If the time of STW is short, it means that the response speed of the system is very high, because of frequent interaction with users. Because low response time leads to a higher user experience.

Old-fashioned collector Serial Old

Serial Old is an old version of Serial, using the tag-collation algorithm, which actually shows a difference between the new and old collectors.

New generation: most of the resources need to be recycled.

Old age: most of the resources do not need to be recycled

Therefore, the new generation of collectors are basically the replication algorithm, and the old collectors are basically the marking-finishing algorithm.

Serial Old is also used by JVM in Client mode.

Parallel Old

Parallel Old is an old version of Parallel Scavenge and a multi-threaded collector with tag-collation algorithm. We have just discussed the system throughput, so when we are very sensitive to the resources of CPU, we can consider the combination of Parallel Scavenge and Parallel Old, a new-old garbage collector.

CMS

The full name of CMS (Concurrent Mark Sweep) uses the mark-and-clear collection algorithm. Focus on the collector with the lowest STW time, if your application is very focused on response time, then you can consider using CMS.

The core steps can be seen from the figure:

First, an initial tag is made to mark all the objects that can be associated from the GCRoots. STW is required, but it does not take much time.

Then concurrent tagging is performed, and multithreading analyzes the reachability of all objects through GC Roots Tracing, which is a time-consuming process.

It will be re-tagged after completion. Because the program is still running normally during the process of concurrent marking, the state of some objects may have changed, so STW is needed for re-tagging. The time used is initial tag < relabel < concurrent tag.

After the marking phase is complete, execution concurrency is clear.

CMS is a garbage collector with obvious advantages, such as multithreading GC and low STW time. But similarly, CMS also has many disadvantages.

Shortcoming

We also mentioned at the beginning that the use of mark-clear algorithms can result in discontiguous memory space, that is, memory fragmentation. If you need to allocate space for larger objects at this time, you will find that there is not enough memory and trigger the Full GC again.

Second, because CMS may take up more CPU resources than throughput-focused collectors, but if the application itself is already sensitive to CPU resources, it will result in less CPU resources available for GC and longer GC time, which will lead to a decrease in system throughput.

G1

The full name of G1 is Garbage First, which is so highly rated by the industry that it is even proposed to be set as the default garbage collector in JDK9. As we mentioned earlier, Parallel Scavenge is more focused on throughput, while CMS is more focused on shorter STW time, so G1 is to achieve high throughput while reducing STW time as much as possible.

We know that the garbage collector mentioned above will divide the continuous heap memory space into the new generation and the old age, and the new generation will be divided into more details, with Eden and two smaller Survivor spaces, both of which are contiguous memory space. G1, on the other hand, is different. It introduces a new concept called Region.

Region is a pile of equal but discontinuous memory space, which also adopts the idea of generation, but there is no physical isolation of other collectors. Region, which belongs to the new generation and the old era, is distributed in all parts of the heap.

The upper H stands for large objects, also known as Humongous Object. In order to prevent frequent copies of large objects, they will be put directly into the old age. What are the characteristics of G1 compared to other garbage collectors?

From a macro point of view, it uses the tag-collation algorithm, while from region to region, it uses a replication algorithm, so G1 will not produce memory fragments like CMS during operation.

In addition, G1 can also shorten the time of STW and execute concurrently with user threads through multiple CPU. And a predictable pause time model can be established to let users know that the time spent on GC should not exceed how many milliseconds in a certain time slice. The reason why the G1 is able to do this is that instead of collecting the entire new and old generation like other collectors, it is planned to avoid region-wide garbage collection of the entire heap.

Summary

This picture comes from the blog in the reference, and it is summarized very well.

Collector serial and parallel or concurrent new generation / old generation algorithm target applicable scenario Serial serial new generation replication algorithm response speed priority Client mode in single CPU environment Serial Old serial old age marking-sorting response speed priority Client mode in single CPU environment, CMS's backup plan ParNew parallel new generation replication algorithm response speed priority when in Server mode with CMS parallel with Parallel Scavenge new generation replication algorithm throughput priority in background operations without too much interaction tasks Parallel Old parallel old age marking-finishing throughput priority in background operations without too much interaction tasks CMS concurrent old age marks-clear response speed priority set The Java application on the server side of the Internet website or Bamp S system G1 concurrent both marking-finishing + replication algorithm response speed gives priority to server-side applications Replace CMS in the future

Thank you for your reading, the above is the content of "how to understand JVM and garbage collection". After the study of this article, I believe you have a deeper understanding of how to understand JVM and garbage collection, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report