GC的四大算法
1.复制算法
年轻代
中使用的是Minor GC,这种GC算法采用的是复制算法(Copying)
JVM把年轻代分为了三部分:1个Eden区和2个幸存区(分别叫from和to)。一般情况下,新创建的对象都会被分配到Eden区(一些大对象特殊处理),这些对象经过第一次Minor GC后,如果仍然存活,将会被移到Survivor区。对象在Survivor区中每熬过一次Minor GC,年龄就会增加1岁,当它的年龄增加到一定程度时,就会被移动到年老代中。因为年轻代中的对象基本都是朝生夕死的(90%以上),所以在年轻代的垃圾回收算法使用的是复制算法,复制算法的基本思想就是将内存分为两块,每次只用其中一块,当这一块内存用完,就将还活着的对象复制到另外一块上面。
复制算法不会产生内存碎片。
谁先清空,谁变成to区
,GC的复制算法会一直重复这样的过程,直到“To”区被填满,“To”区被填满之后,会将所有对象移动到年老代中。因为Eden区对象一般存活率较低,一般的,使用两块10%的内存作为空闲和活动区间,而另外80%的内存,则是用来给新建对象分配内存的。一旦发生GC,将10%的from活动区间与另外80%中存活的eden对象转移到10%的to空闲区间,接下来,将之前90%的内存全部释放,以此类推。
2.标记清除算法
第一步:标记(Mark)
第二部:清楚(Sweep):回收为被标记对象
3.标记压缩(Mark-Compact)
4.标记清除压缩(Mark-Sweep-Compact)
总结
内存效率:复制算法>标记清除算法>标记压缩算法(时间复杂度)
内存整齐度:复制算法=标记压缩算法>标记清除算法
内存利用率:标记压缩=标记清楚>复制算法
没有最好的算法,只有最合适的算法
1、年轻区域特点是区域相对老年代较小,对像存活率低
这种情况
复制算法
的回收整理,速度是最快的。复制算法的效率只和当前存活对像大小有关,因而很适用于年轻代的回收。而复制算法内存利用率不高的问题,通过hotspot中的两个survivor的设计得到缓解。
2老年代的特点是区域较大,对像存活率高
存在大量存活率高的对像,复制算法明显变得不合适。一般是由
标记清除或者是标记清除与标记整理
的混合实现。
算法明显变得不合适。一般是由
标记清除或者是标记清除与标记整理
的混合实现。
Mark阶段的开销与存活对像的数量成正比,这点上说来,对于老年代,标记清除或者标记整理有一些不符,但可以通过多核/线程利用,对并发、并行的形式提标记效率