深入理解JAVA虚拟机学习笔记5——垃圾收集算法

话不多说,直接上内容,书中介绍了四种算法。

1. 标记-清除算法:这是最基础的算法,后续的算法都是在此算法基础上做出的改进。

该算法包括两个过程:

标记——将对象回收状态进行标记,这个在以前的笔记中已经做了介绍,这里不再赘述。

清除——回收的时候直接将标记为可回收的对象清除。

缺点:1.1效率问题:标记和清除两个过程的效率都不高;

1.2. 空间问题:从图中可以看出,回收之后的内存上产生了大量不连续的内存碎片,过小的内存空间不能被分配给大的对象使用,只能占用更大的空闲内存空间,这样又会产生新的内存碎片,直至无法满足更大的内存需求,就要开始又一次垃圾收集。

2. 复制算法:解决标记-清除算法的效率问题(适用于新生代)。

算法思想:将内存分为相等的两块,比如a和b,程序运行时的内存分配都在a中操作,当垃圾回收的时候(在回收之前标记过程还是有的),将a中需要存活的对象信息依次直接复制到b上(这样,在b中的内存使用一直都是连续的),然后把a的空间直接清空(这简直是truncate table a和delete from a where id in(1,2,3,4……)的差距)。

缺点:内存的最大可用空间变为只有原来的一半。

原书中的配图是这样的,笔者感觉下面图的看起来更加直观一些。

另外,现代的商业虚拟机(包括JAVA的HotSpot)都是采用这种方法回收新生代。

不过这里不是按照1:1分配的了,而是将Eden,Survivor(From),Survivor(To)三个区域(对新生代、老年代不太明确的,有疑问的话可以看一下上一篇,已经特别介绍过了)按照8:1:1分配的。

其中Eden和Survivor(From)可以当作上图中的a,占90%;Survivor(To)相当于b,占10%。

之所以这样分配是因为新生代中的对象生命周期较短,回收率非常高(IBM研究表明达到98%)。

这里还有一种情况,当a回收时,存活对象大于10%,即超过b的空间大小的时候,这些对象将通过分配担保机制进入到老年代。

3. 标记-整理算法:解决复制算法在对象存活率较高,要进行多次复制,效率变低的问题(老年代上的对象存活率很高,此算法适用于老年代)。

步骤:首先也是标志对象回收状态。然后进行整理,将存活的对象向一端挪动,将存活的对象集中到一端,剩下的全部作为可用空间。示意图如下:

4. 分代收集算法:实际上就是根据不同的对象存活周期的特点采用不同算法进行回收,上面对于适用的情况已经做出了描述。

怎么样,其实对照的看一下,是不是很简单。

喜欢文章或想一起学习的朋友可以关注我,我将会持续更新,有什么疑问或文中有不当之处请给我留言,真诚地希望能与大家一起交流探讨,学习进步。


猜你喜欢

转载自blog.csdn.net/wuyuwuqiu/article/details/80475316