Introduction
What is the ultimate algorithm?
In fact, it is the algorithm used by the current JVM, not the real ultimate. Maybe a few years later, there will be a new ultimate algorithm, and there will almost certainly be one, because LZ believes in the abilities of advanced people.
So how does the generational collection algorithm handle GC?
Object Classification
As mentioned in the previous chapter, the generational collection algorithm is based on the different characteristics of the object, and using appropriate algorithms, there is no actual new algorithm produced. Rather than saying that the generational collection algorithm is the fourth algorithm, it is better to say that it is a practical application of the first three algorithms.
First, let’s discuss the different characteristics of objects. Next, LZ and everyone will choose GC algorithms for these objects.
Objects in memory can be roughly divided into three types according to the length of their life cycles. The following names are all LZ’s personal names.
1. Objects that die young: Objects that are born and disappear. In layman’s terms, they are objects that will die before they can live long.
Examples: local variables of a certain method, temporary variables within a loop, etc.
2. Immortal objects: This type of object generally lives longer and is still alive at a very old age. But in the final analysis, immortal objects are almost certain to die sooner or later, but only almost.
Examples: cache objects, database connection objects, singleton objects (singleton mode), etc.
3. Immortal objects: Such objects are generally almost immortal once they are born. They will almost always be immortal. Remember, they are just almost immortal.
Examples: Objects in the String pool (flyweight mode), loaded class information, etc.
The memory area corresponding to the object
Do you still remember the division of memory by the JVM when we introduced memory management earlier?
We map the above three objects to the memory area, that is, the premature objects and the immortal objects are in the JAVA heap, and the immortal objects are in the method area.
We have already said in the previous chapter that for the JAVA heap, the JVM specification requires that GC must be implemented. Therefore, for premature objects and immortal objects, death is almost an inevitable outcome, but it is only almost inevitable. There will be some objects that will survive until the application ends. However, the JVM specification does not require GC in the method area, so assuming that a JVM implementation does not implement GC in the method area, then the immortal object is a truly immortal object.
Because the life cycle of immortal objects is too long, the generational collection algorithm is designed for the JAVA heap, that is, for premature objects and old immortal objects.
Object recycling of JAVA heap (aborted objects and immortal objects)
With the above analysis, let’s take a look at how the generational collection algorithm handles the memory recycling of JAVA heap, that is, premature objects Recycling of objects and immortal objects.
Dead objects: This type of object is born and disappears rapidly and has a short survival time. Do you still remember the requirements for using the replication algorithm? That is, the object survival rate cannot be too high, so premature objects are most suitable for using the replication algorithm.
Little question: What should I do if 50% of the memory is wasted?
Answer: Because the survival rate of premature objects is generally low, you do not need to use 50% of the memory as free. Generally, two 10% of the memory are used as the free and active range, and the other 80% of the memory is Used to allocate memory for new objects. Once a GC occurs, 10% of the active range and the other 80% of surviving objects are transferred to 10% of the free range. Next, all the previous 90% of the memory is released, and so on.
In order to let you see this GC process more clearly, LZ gives the following diagram.
The picture marks the memory status of each of the three areas at each stage. I believe that looking at the picture, its GC process is not difficult to understand.
However, there are two points that LZ needs to mention. The first point is that by using this method, we only waste 10% of the memory. This is acceptable, because we exchange for neat arrangement of memory and GC speed. The second point is that the premise of this strategy is that the memory occupied by each surviving object cannot exceed this 10% size. Once it exceeds, the extra objects will not be copied.
In order to solve the above unexpected situation, that is, when the memory occupied by the surviving object is too large, experts divide the JAVA heap into two parts to handle. The above three areas are the first part, called the new generation or young generation. . The remaining part, which is dedicated to storing old and immortal objects, is called the old generation.
Isn’t it a very appropriate name? Let's take a look at how to deal with old immortal objects.
Old immortal objects: The survival rate of this type of objects is very high, because most of them are transferred from the new generation. Just like people, after living for a long time, they become old and immortal.
Normally, when the following two situations occur, the object will be transferred from the new generation area to the old area.
1. Every object in the new generation will have an age. When the age of these objects reaches a certain level (the age is the number of GCs that have survived, if the object survives each GC, the age will be increased by 1) , it will be transferred to the old generation, and the age value of this transfer to the old generation can generally be set in the JVM.
2. When the memory occupied by surviving objects in the new generation exceeds 10%, the excess objects will be placed in the old generation. At this time, the old generation is the "backup warehouse" of the new generation.
Based on the characteristics of the old and immortal object, it is obviously no longer suitable to use the replication algorithm because its survival rate is too high, and don’t forget that if the old generation uses the replication algorithm again, it will not have a backup warehouse. Therefore, generally only mark/organize or mark/clear algorithms can be used for old immortal objects.
Object recycling in the method area (immortal objects)
The above two situations have solved most of the GC problems, because the JAVA heap is the main focus of the GC, and the above has also been included The entire content of the generational collection algorithm has been revealed, and the subsequent recycling of immortal objects is no longer part of the generational collection algorithm.
Immortal objects exist in the method area. In our commonly used hotspot virtual machine (JDK default JVM), the method area is also affectionately called the permanent generation. It is a very appropriate name, isn't it?
In fact, a long time ago, there was no permanent generation. At that time, the permanent generation and the old generation were stored together, which contained instance information and class information of JAVA classes. However, it was later discovered that unloading of class information rarely occurs, so the two were separated. Fortunately, doing so does improve performance quite a bit. So the permanent generation was split.
The GC in this part of the area uses a similar method to the old generation. Since there is no "standby warehouse", both can only use mark/clear and mark/organize algorithms.
Timing of recycling
When the JVM performs GC, it does not recycle the above three memory areas together every time. Most of the time, it recycles the new generation. Therefore, GC is divided into two types according to the recycling area, one is ordinary GC (minor GC), and the other is global GC (major GC or Full GC). The areas they target are as follows.
Normal GC (minor GC): GC only for the new generation area.
Global GC (major GC or Full GC): GC for the old generation, occasionally accompanied by GC for the new generation and GC for the permanent generation.
Since the GC effect of the old generation and the permanent generation is relatively poor, and the memory usage of the two grows slowly, it usually takes several ordinary GCs to trigger a global GC.
Conclusion
The above is the JVM memory management------the refined explanation of the GC algorithm (five minutes to teach you the ultimate algorithm---generational collection algorithm) Content, please pay attention to the PHP Chinese website (www.php.cn) for more related content!