在Java中常见的垃圾回收算法有:标记-清除算法,标记-整理算法,复制算法,分代算法等
而垃圾回收器有:Minor GC (新生代垃圾回收),Magor GC(老生代垃圾回收),Full GC(全局垃圾回收)
是Java垃圾回收算法中最常见的一种垃圾回收算法,它的核心思想是统一标记可回收的对象,然后统一进行垃圾回收 优点:执行效率比较高,实现简单 缺点:使用标记-清除算法会出现大量的垃圾碎片,如果需要一大片连续的内存空间时候,此种垃圾回收的效率就会打折扣。
标记-整理算法其实是标记-清除算法的一种升级,在统一标记后并不会立即执行垃圾回收,而是将存活的对象移动到另一端,然后清理端外的垃圾对象。 优点:不会存在垃圾碎片的问题 缺点:执行效率比较低下,因为在标记后还需要进行整理存活对象到另一端
复制算法是标记-整理算法的一种升级,它的目的就是解决标记-整理算法的效率问题,它将可用内存区域按容量划分为两块大小相等的区域,然后在一块区域进行使用,当需要垃圾回收的时候,会将使用区域的存活对象复制到另一块未使用的区域,然后统一清除使用区域的垃圾对象 优点:执行效率高,不会存在垃圾碎片 缺点:内存空间的利用率比较低
分代算法就是将堆内存区域划分为新生代,老生代,然后在各自的区域进行垃圾回收的一种算法
分代算法的大致流程如下:
将堆内存区域划分为新生代,老生代,新生代占比1/3,老生代占比2/3,然后新生代区域又细分为3个区域:end区,To Survivor ,From Survivor占比分别为8:1:1 执行流程大致如下: 1.end区+from Survivor区存活的对象放入 To Survivor区
2.清空end区,from Survivor区
3.交换from Survivor区,To Survivor区
每交换一次存活的对象的年龄+1,当对象的年龄到达15时(HostPot默认是15),就会将该对象放进老生代,当老生代的区域不够用时,就会触发Full GC(全局垃圾回收)。
三类垃圾回收器的关系乳如下:
在新生代的Serial,ParNew,parallel Scavenge 在老生代的Serial Old,CMS,Parallel Old 已经后续一直在沿用的默认的垃圾回收器G1
在新生代的垃圾回收器常采用的垃圾回收算法是复制算法,在老生代采用的则是标记-整理算法
Serial,Serial Old是单线程环境下的串行执行的,不支持并发操作,意味着在进行垃圾回收时会阻塞用户线程,直到垃圾收集完成。
ParNew 相当于Serial的升级版本,唯一的区别就是ParNew 采用的并行回收,适用于多线程环境下
Parallel Scavenge,Parallel Old是专注于吞吐量的垃圾回收器 (吞吐量 = 用户线程执行时间/总时间 * 100% = 用户线程执行时间/(GC时间+用户线程执行时间)* 100%)
CMS:专注于最短停顿时间的垃圾回收器