JVM memory management ------ GC algorithm refined solution

JVM memory management ------ GC algorithm refined solution (--- generational collection algorithm)

object classification

 

         As mentioned in the previous chapter, the generational collection algorithm is based on the different characteristics of the object, and using the appropriate algorithm, there is no actual new algorithm generated. The generational collection algorithm is not so much the fourth algorithm as it is a practical application of the first three .

         First, let's discuss the different characteristics of objects. Next, LZ and you 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 named after LZ individuals.

         1. The object of premature death : the object of life and death, in layman's terms, it is the object of death that will not live for a long time.

             Examples : local variables in a method, temporary variables in loops, etc.

         2. Immortal objects : These objects generally live for a long time, and they are not dead at a very old age, but in the final analysis, the immortal objects will almost die sooner or later, but only almost.

             Examples : cache objects, database connection objects, singleton objects (singleton pattern), etc.

         3. Immortal objects : Such objects are generally almost immortal once they are born, and they will almost always be immortal. Remember, they are almost immortal.

             Examples : objects in the String pool (flyweight pattern), loaded class information, etc.

         

The memory area corresponding to the object

 

         Remember the division of memory by the JVM when we introduced memory management earlier?

         We correspond the above three objects to the memory area, that is, the aborted object and the old immortal object are both in the JAVA heap, and the immortal object is in the method area .

         In the previous chapter, we have already said that for the JAVA heap, the JVM specification requires that GC must be implemented. Therefore, for dead objects and old undead objects, death is almost inevitable, but it is only almost, and there will inevitably be some. Objects live until the end of the application. However, the JVM specification does not require the GC of the method area, so if a JVM implementation does not implement GC for the method area, then the immortal object is really an 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 dead objects and old immortal objects .

         

JAVA heap object recycling (dead objects and old undead objects)

 

          With the above analysis, let's take a look at how the generational collection algorithm handles the memory recovery of the JAVA heap, that is, the recovery of aborted objects and old undead objects.

          Aborted objects : These objects are born and die, and the survival time is short. Remember the requirements for the use of the replication algorithm? That is, the object survival rate cannot be too high, so the aborted object is the most suitable for using the replication algorithm .

          Small question: what should I do if 50% of the memory is wasted?

          Answer: Because the survival rate of aborted objects is generally low, 50% of the memory can not be used as idle. Generally, two 10% of the memory is used as the free and active area, and the other 80% of the memory is used for New object allocates memory. Once GC occurs, 10% of the active range and the other 80% of surviving objects are transferred to the 10% free range, and then 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.

         In the figure, the memory conditions of the three areas at each stage are marked. I believe that looking at the picture, its GC process is not difficult to understand.

         However, there are two points that need to be mentioned. The first point is that using this method, we only waste 10% of the memory, which is acceptable, because we have exchanged the 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 able to be copied .

         In order to solve the above unexpected situation, that is, when the memory occupied by the surviving objects is too large, the experts divide the JAVA heap into two parts to deal with. The above three areas are the first part, which is called the new generation or the young generation . The remaining part, dedicated to storing old undead objects, is called the old generation .

         Is it an apt name? Let's take a look at how old undead objects are handled.

         Old undead objects : This type of object has a very high survival rate, because most of them are transferred from the young generation. Just like human beings, they become immortal as they live for a long time.

         Usually, when the following two situations occur, the object will be transferred from the young generation area to the old belt area.

         1. Each 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, each GC if the object survives, the age will increase by 1), then It is 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" for the new generation.

         For the characteristics of old immortal objects, it is obviously no longer suitable to use the replication algorithm, because its survival rate is too high, and don't forget, if the old generation uses the replication algorithm, it does not have a backup warehouse. Therefore, in general , only marking/sorting or marking/clearing algorithms can be used for old undead objects .

 

方法区的对象回收(不灭对象)

 

         以上两种情况已经解决了GC的大部分问题,因为JAVA堆是GC的主要关注对象,而以上也已经包含了分代搜集算法的全部内容,接下来对于不灭对象的回收,已经不属于分代搜集算法的内容。

         不灭对象存在于方法区,在我们常用的hotspot虚拟机(JDK默认的JVM)中,方法区也被亲切的称为永久代,又是一个很贴切的名字不是吗?

         其实在很久很久以前,是不存在永久代的。当时永久代与年老代都存放在一起,里面包含了JAVA类的实例信息以及类信息。但是后来发现,对于类信息的卸载几乎很少发生,因此便将二者分离开来。幸运的是,这样做确实提高了不少性能。于是永久代便被拆分出来了。

         这一部分区域的GC与年老代采用相似的方法,由于都没有“备用仓库”,二者都是只能使用标记/清除和标记/整理算法。

         

回收的时机

 

         JVM在进行GC时,并非每次都对上面三个内存区域一起回收的,大部分时候回收的都是指新生代。因此GC按照回收的区域又分了两种类型,一种是普通GC(minor GC),一种是全局GC(major GC or Full GC),它们所针对的区域如下。

         普通GC(minor GC):只针对新生代区域的GC。

         全局GC(major GC or Full GC):针对年老代的GC,偶尔伴随对新生代的GC以及对永久代的GC。

         由于年老代与永久代相对来说GC效果不好,而且二者的内存使用增长速度也慢,因此一般情况下,需要经过好几次普通GC,才会触发一次全局GC。

         

结束语

 

         GC的相关内容基本上就这些了,下一章我们一起探讨一下具体的GC实现都有哪些。

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325927620&siteId=291194637