垃圾回收器的组合情况
第一种组合serial和serialOld
Serial:是一种单线程串行回收年轻代的垃圾回收器
优点:单cpu处理器下的吞吐量非常高
缺点:多cpu处理器下的吞吐量不如其他的垃圾回收器,如果堆的内存非常大,会让用户处于较长时间的等待
应用场景:编写java客户端程序,或者单cpu硬件下的场景
SerialOld:是一种单线程串行回收老年代的垃圾回收器
优点:单cpu处理器下的吞吐量非常高
缺点:多cpu处理器下的吞吐量不如其他的垃圾回收器,如果堆的内存非常大,会让用户处于较长时间的等待
应用场景:与Serial组合使用,CMS在特定情况下会调用SerialOld
第二种组合ParNew和CMS
ParNew:多线程回收年轻代的垃圾回收器
优点:多cpu下执行时间短
缺点:吞吐量不如G1,JDK9之后不建议在使用
应用场景:与老年代的CMS配合使用
CMS(Current Mark Sweep):关注的是系统的执行时间,允许用户线程和垃圾回收线程同时执行,减少用户等待的时间
CMS的执行步骤
1,初始标记:极短的时间将GC Root关联的对象进行标记
2,并发标记:标记所有的对象,用户线程不用暂停
3,重新标记:由于并发阶段对象的状态可能发生变化,存在错标,漏标的问题,需要重新标记
4,并发清理:清理死亡对象,用户线程不需要暂停
优点:垃圾回收的时间短,用户等待时间减少,体验感上升
缺点:
1,出现碎片化的内存(使用的是标记-清理算法),CMS会在Full GC之后对内存碎片进行整理,可以设置几次Full GC后整理
2,浮动垃圾问题:在并发清理阶段,由于用户线程还在执行,就可能出现刚创建的对象没用之后,没有被回收
3,退化问题:如果老年代的内存无法分配,CMS就会退化成SerialOld单线程回收老年代
第三种组合Parallel Scavenge和Parallel Old
Parallel Scavenge:多线程并行回收年轻代的垃圾回收器,关注的是系统的吞吐量,具有自动调整堆内存分配的特点
优点:可以提高系统的吞吐量,而且手动可控
缺点:不能保证单次的执行时间
应用场景:后台任务,不需要与用户交互,并且容易尝试大量对象比如,数据处理,大文件导出
Parallel Old:为Parallel Scavenge专门设计,并发处理老年代的垃圾回收器
优点:并发收集,多核cpu下效率高
缺点:暂停时间长
应用场景:与Parallel Scavenge配套使用
最后一种G1垃圾回收器
内存结构:将堆划分成多个大小相等的区,称为Region区,区域不要求是连续的,分为Eden,Survivor,Old区
Region空间的大小为堆内存/2048,也可以通过虚拟机参数来指定Region大小
两种回收方式:年轻代回收(Young GC),老年代回收(Mixed GC)
G1垃圾回收器的执行流程
1,新创建的对象会放在Eden区,当G1判断年轻代的内存不足时(max默认为60%),会执行Young GC
2,标记出Eden,Survivor区存活的对象
3,根据最大暂停时间来选择某些区域将存活的对象复制到一个新的Survivor区(标记这些存活对象的年龄+1),清空这些区域
每次Yong GC,都会去记录回收每个Eden区和Survivor区的平均时间,下次回收时,以平均时间为参照,根据配置的最大暂停时间来选择回收多少个区域
4,后续Young GC相同,只不过Survivor区存活的对象会被搬运到另外一个Survivor区
5,当某个Survivor区的对象存活时间超过了阈值(默认是15),就会被放入老年代中
6,部分堆对象超过了Region区大小的一半,会被直接放入老年代,这种老年代称为Humongous区,如果对象过大会横跨Region区
7,多次回收后,会出现多个Old老年代区,此时总堆占有率达到阈值(max为45%),会执行Mixed GC 回收所有年轻代,部分老年代以及大对象区(Humongous)
8,Mixed GC:包括了初始标记,并发标记,最终标记,并发清理
9,如果清理过程中发现没有足够的Region区来转移对象,那么就会执行Full GC
优点:
1,对回收较大的堆内存,延迟可控(在年轻代回收和老年代回收时,根据最大暂停时间来选择回收部分区域,而不是全部回收)
2,使用复制算法,不会产生内存碎片
缺点:
JDK8以前不成熟
应用场景:JDK8以后建议默认使用