Original:Understanding Java Garbage Collection
jvm--Become a Java GC expert (1)
What are the benefits of understanding how the Java garbage collection mechanism (garbagecollection, referred to as GC) works? As a software engineer, to satisfy his curiosity to understand him is one of the reasons, and understand that the GC works more to let us write better performance, more robust Java applications.
This is just my personal concept, but I believe that being proficient in GC is a necessary condition for being a good Java engineer. If you are interested in how GC works, it means that you already have project experience in developing Java applications of a certain size. If you are already careful to choose which GC algorithm your Java application should use, it means that you are fully aware of the features and details of the project you are developing. Of course, this may not be the standard to measure a good Java engineer. But few would oppose one of the points I mentioned earlier: Understanding and mastering how GC works is a necessary condition for becoming a great Java engineer.
This is the first article in the "become a Java GC Expert" series, and I'll do some introduction to the GC. In the following article I will discuss some examples of NHN on analyzing GC status and GC tuning.
The main purpose of this paper is to go into a brief introduction to the GC to help us understand what he is. I hope he can give you some help. In fact, my students have published some very good papers on Twitter: A few great articles on Java internals. If you are interested, you can browse.
Now back to the GC issue, you should know a term "stop-the-world" before you learn the GC. Regardless of the garbage collection algorithm you use, Stop-the-world occurs when the application is performing garbage collection. When stop-the-world occurs, all threads, except the thread that executes the GC, stop the task they are performing. These forced-to-stop tasks can only continue until the GC Recycle task is completed. GC tuning typically reduces the time that stop-the-world occurs as much as possible.
Generation of garbage collection
The Java program code does not display the declaration and frees a piece of memory space. Some programmers may set the associated object object reference to null or manually invoke the System.GC () method to display the freed piece of memory space. Setting a reference to NULL is not a big problem, but manually calling the System.GC () method can seriously affect the execution efficiency of the system, which is strictly forbidden. (thankfully, until now NHN programmers have not yet done that)
In Java, since developers cannot manually invoke the System.GC () method in code to free memory, these should be given to the Java garbage collector, which collects objects that are no longer needed and removes them and frees up memory. The creation of the garbage collector is based on the following two assumptions (hypotheses). (They are called prerequisites (suppositions) or prerequisites (preconditions) are more appropriate than assumptions. )
A) Large number of instance objects become unreachable within a short period of time (unreachable)
b) Only a small number of references to the old instance object point to the new object
These assumptions are assumed to be the "weak-generation hypothesis"--weakgenerational hypothesis. So in order to present this hypothesis, the HotSpot VM is physically divided into two areas-the "young generation" and the "Old Generation" (Younggeneration and Generation).
Young generation: Most new objects will be stored here first. When a large number of objects quickly become unreachable, some objects created in the younger generation disappear (recycled). When the objects in the young generation disappear, the "minor GC" executes.
Old age: the instance objects that have not become unreachable and have been in stock in the young generation are moved here (that is, in the old generation). In general, older generations of memory space will be larger than younger generations. As a result, the frequency of garbage collection occurs in older generations is lower than in younger generations. When objects in the old generation disappeared (recycled), the "major GC" was executed (or "full GC").
The persistent generation (permanent generation) is also known as the method domain (methods areas), which is used to store the metadata of classes and methods. So it is clear that this area is not used to persist the surviving instances of those older generations. Garbage collection is also possible in this area, and the garbage collection that occurs here is also categorized as "Major GC", also known as "full GC".
Some people will wonder:
What if an instance object in an aging generation holds a reference to an instance object in a young generation? (That is, when the young generation of GC, how to check if the instance object in the old generation of reference, is to traverse the entire old generation all instances of the object is the full value of the condition or how to handle it?) )。
In this case, there is a block of 512 bytes of data in the old age, called "cardtable", when an object in the old generation is referring to the young generation object, and this object in the older generation is recorded in this data block. When a young generation is garbage collected ("minor GC"), only the contents of the "card table" in the older generation are searched, which in turn determines whether this object is referenced in the younger generation, rather than checking whether all objects in the old generation are holding this object reference. This "card table" is managed by "write barrier" and "writer barrier" is a device that improves the efficiency of "minor GC" execution. Although the design is somewhat complex because of the existence of "card table", it also greatly reduces the overall time taken by the garbage collector.
Young generation composition Structure
In order to understand the GC, first to understand the young generation used to hold all the newly created instance objects, the young generation is divided into three pieces:
A) A Eden space (Eden, don't think it's good or weird to be literal)
b) Two survivor spaces (survivor space, still no longer literal)
A total of three spaces: two of which are survivor spaces, and the steps to perform the events in each space are as follows:
1. Most new objects will be assigned to Eden Space.
2. After Edenspace executes the first GC, the instance objects that continue to exist are transferred to survivor space.
3. After Edenspace executes the GC again, the instance object that continues to exist is transferred to the survivor space that already has the instance object.
4. Once the survivor space is full, the objects that continue to exist will be transferred to another survivor space. Then the front survivor space will be emptied.
5. The above steps are repeated until a certain number of instances of the surviving instance objects are transferred to the older generation.
Note: The goal is to increase the chance of being recycled before the object is transferred to the old age generation.
As can be seen from the above steps, one of the survivor space must be empty. If your two survivor space has data or no data, then it's likely to mean something wrong with your program.
Shows how the data was transferred through the minor GC to the older generation:
It is important to note that in a hotspot VM, two technologies are applied and the memory allocation is accelerated:
1.bump-the-pointer
2.TLABs (thread-local Allocation buffers).
Bump-the-pointer (pointer) technology tracks the location of the last instance object added to Eden space. This object will be placed with the top of the edenspace. When a new object is created, only the last object that is stored in Eden space needs to be checked for information about whether the new object can be stored in Eden space. If possible, it will be stored at the top of the edenspace. So when a new object is created and the last object to be stored is detected, this mechanism greatly increases the efficiency of memory allocation. However, this method is not suitable for multi-threaded environment, multi-threaded operation because of the lock and some threads will not be able to perform properly, which results in a greatly reduced efficiency.
Tlabs is designed for this situation. Tlabs allows each thread to take a small portion of Eden space as its own operand, so that each thread can use Bump-top-pointer technology to speed up memory allocation, thereby avoiding threading problems with locks.
So far is an overview of the young generation. Readers don't have to remember the two techniques I mentioned above to speed up the allocation of memory, even if they do not know that they do not affect the learning of later content. But keep in mind that new objects are stored in Eden space, and objects that are still alive through various processing will be transferred to older generations.
Garbage collection for older generations
Full GC execution is triggered when the instance object is stored in the old generation. The execution is related to the type of GC, so understanding the type of GC can help us understand the situation of execution. According to JDK7, there are 5 GC types:
1. SERIALGC
2. PARALLELGC
3. Parallelold GC
4. Concurrentmark & Sweep GC (or "CMS")
5. Garbagefirst (G1) GC
As mentioned above, the server must not use the serial GC, this type of GC is only suitable for use on single-threaded clients. Using this type of GC can greatly reduce the execution efficiency of the program.
Serial GC (-XX:+USESERIALGC)
The GC algorithm used by the young generation (Bump-top-pointer,tlabs) has been mentioned earlier, and the GC algorithm used by older generations is called "Mark-sweep-compact" (Mark-erase-compress).
1. The first step of the algorithm is to mark the surviving objects of the old generation
2. Check all objects in the heap, reclaim all unmarked objects, and leave only the tagged objects before and after
3. All objects are discharged from front to back in the heap, and the heap space is divided into two parts, one part holds the object, the other part is not stored (that is, the compressed part)
The Serial GC is suitable for small memory, single-core machines.
Parallel GC (-XX:+USEPARALLELGC)
From the picture you can easily find the difference between the two. Serial GC uses a single thread, while parallel uses multithreading and is faster. The efficiency of the Parallel GC is higher on large, multi-core CPUs on memory. It is also often referred to as "THROUGHPUTGC".
Parallel old GC (-XX:USEPARALLELOLDGC)
The Parallel old GC is supported only after JDK1.5. Compared to PARALLELGC, the only difference is that the GC algorithm is different. The Parallelold GC algorithm is divided into three steps: Tag-digest-compression. The summary is to identify the surviving objects in the previously performed GC, which is different from the sweep step in the parallel GC, and the details of the execution are more complicated.
CMS GC (-XX:USECONCMARKSWEEPGC)
, Concurrent Mark-sweep GC is more complex than several other GCs.
The initial initialization mark (initial mark) is relatively simple, and the closest surviving object to ClassLoader is searched first. So the pause time is very short.
In the parallel tag (concurrent mark) step, the objects referenced by the surviving objects are only confirmed to have been tracked and verified. The difference in this step is that when other threads are executed, he is also executing.
The re-tagging (remark) step, those newly added, and the object at which the concurrent tag step is stopped are examined.
Finally, in parallel switching (concurrent sweep) This step, garbage collection begins to execute. As you can see, the garbage collection executes while the other threads are still executing. So the time for this GC to pause is very short. CMCGC, also known as low latency GC, is used for programs that are particularly demanding on response times.
There are pros and cons, and the CMS has some drawbacks:
1. More memory, stronger CPU required than other GC types
2. Compression is not performed automatically by default
So you have to be thoughtful before you decide if you need to use this GC. At the same time, if you need to perform a compression task because of too much memory fragmentation, the Stop-the-world time is longer than any other GC, so you need to determine how often this compression occurs and how time is spent.
G1 GC
If you want to understand the G1 GC, then throw away the concept of the younger generation and the older generation. As the positive display, each instance object is assigned to each grid, followed by the GC execution. Once a region is filled with data, the instance object is assigned to another zone, and the GC executes again. There are no steps to move from the young generation to the old generation. The significance of this GC type is to replace CMSGC because the CMS GC has caused a lot of problems and complaints over a long period of time.
The biggest advantage of G1 GC is that he performs more efficiently than any type of GC. But in JDK1.6, this is just a preview, for testing. was formally added to the JDK7. In my opinion, we need at least a very long test phase to apply it to the actual service, so you should probably wait a long time. And I heard more than once about the JVM macro machine that was caused by the use of JDK6 's G1. All we have to do is wait until he is more stable and use it.
I'm going to talk about GC tuning in the next chapter, but before I do, I want to clarify one thing to the reader: if all the instance objects in the app are of the same type and size, then all the GC parameters for company was are the same. However, the size and longevity of the objects created by was will vary depending on the device and the operating environment to which was is dependent. In other words, running a well-performing GC parameter "a" in a running environment does not necessarily suit another operating environment. We need to find the parameters that are appropriate for each was thread, and continuously monitor and optimize the was instance on each device. This is not the conclusion I get from personal experience, but from the discussion in JavaOne 2010 of the engineers who are responsible for the development of Oracle Java virtual machines.
In this article we briefly introduce the GC mechanism of Java, please continue with our follow-up article, we will discuss how to monitor the JAVAGC status and GC tuning.
In addition, I recommend a December 2011 release of "Java Performance" (Amazon, if the company provides accounts, you can also use Safari to read online), as well as the Oracle's official website published in the white paper "Java Hotspottm Virtual Machine Memory Management "(this book is not the same as Java performance optimization)
Author Sangminlee, NHN, performance Engineer Lab senior engineer.
jvm--become a Java GC expert (1)