您的位置:首页 > 其它

JVM系列(4)-垃圾收集算法

2018-01-03 22:34 393 查看
上一节讲了判断"垃圾"的方法,有引用计数和可达性分析两种方法。这一节看下,回收这些“垃圾”的方法。

方法1:标记-清除算法

见名知意,先标记,再清除;标记出所有的可回收对象后,统一回收。

缺点:容易产生大量的内存碎片,如果分配的对象占用内存较大,同时又找不到足够大的连续空间,则只能再次触发一次垃圾回收。

回收前:



回收后:



方法2:复制算法

复制算法是将内存划分为大小相等的两个区域,每次只使用其中的一块区域。当这一块内存不够分配了,或者用完了,就将存活对象复制到另外一块区域,而这块区域就一次全部清除。

缺点:内存使用率低,只有50%。

回收前:



回收后:



每次只使用一半是不是有些浪费呢?为什么要等分内存,按其他比例分配不行么?不过还真有研究团队专门研究了一下这个问题,得出的结论是不必等分,因为98%的新生代都是“朝生夕死”。可以将内存分为三个区间,一个Eden区间,两个Survivor区间,Eden:Survivor = 8 : 1, 每次只使用一个Survivor区和Eden区,保留一个Survivor区。当垃圾回收时,将所有的存活对象都复制到保留的那个Survivor区,然后清理掉刚才使用的Eden区和Survivor区。

如果保留的Survivor区装不下Eden区和使用的Survivor区中的存活对象,怎么办?

那就依赖老年代分配担保。



方法3:标记-整理算法

标记-整理算法是以标记-清除算法为基础的。标记过程相同,这里清除的步骤有差别,整理并不是直接清除,而是将所有存活对象向前移动,然后清理掉端边界以外的内存,就像是被整理了一样。

回收前:



回收后:



方法4:分代收集算法

首先怎么理解这个“分代”。按年龄划分,新new出来的对象,也就是刚出生的对象就是新生代。新生代躲过多次GC,还没有被回收的就是老年代。根据不同分代的特点采用不同的收集算法,就是分代收集。

例如,在新生代中,每次垃圾收集,只有一小部分存活,就适合用复制算法;在老年代中,因为都是老寿星,每次只有一小部分被收集,就适合采用标记-清除或者标记-整理算法。

今天就到这儿,明天看下HotSpot的算法实现。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  jvm