一、新生代收集器
1.serial
2.parNew
3.parallel scavenge
二、老年代收集器
1.serial old
2.parallel old
3.cms
三、堆内存垃圾收集器
1. g1
ps:新老代的收集器是可以搭配使用的。
四、serial 垃圾收集器
1.概念:Serial 是一款用于新生代的单线程收集器,采用复制算法进行垃圾收集。Serial 进行垃圾收集时,不仅只用一条线程执行垃圾收集工作,它在收集的同时,所有的用户线程必须暂停(Stop The World)
2.场景:Client 模式(桌面应用);单核服务器。
3.使用: -XX:+UserSerialGC
五、parNew 垃圾收集器
1.概念:ParNew 就是一个 Serial 的多线程版本,其它与Serial并无区别。ParNew 在单核 CPU 环境并不会比 Serial 收集器达到更好的效果,它默认开启的收集线程数和 CPU 数量一致,可以通过 -XX:ParallelGCThreads 来设置垃圾收集的线程数。
2.场景:多核服务器;与 CMS 收集器搭配使用。当使用 -XX:+UserConcMarkSweepGC 来选择 CMS 作为老年代收集器时,新生代收集器默认就是 ParNew,也可以用 -XX:+UseParNewGC 来指定使用 ParNew 作为新生代收集器
3.使用: -XX:+UseParNewGC
六、parallel scavenge 垃圾收集器
1.概念:Parallel Scavenge 也是一款用于新生代的多线程收集器,与 ParNew 的不同之处是ParNew 的目标是尽可能缩短垃圾收集时用户线程的停顿时间,Parallel Scavenge 的目标是达到一个可控制的吞吐量。
吞吐量 = 运行用户代代码时间/(运行用户代码时间+垃圾收集时间)
2.场景:注重吞吐量,高效利用 CPU,需要高效运算且不需要太多交互
3.使用: -XX:+UseParallelGC
-XX:MaxGCPauseMillis -->设置收集器尽可能在多长时间内完成内存回收
-XX:GCTimeRatio --> 设置吞吐量
七、Serial Old 垃圾收集器
1.概念:Serial Old 收集器是 Serial 的老年代版本,同样是一个单线程收集器,采用标记-整理算法。
2.场景:Client 模式(桌面应用);单核服务器;与 Parallel Scavenge 收集器搭配;作为 CMS 收集器的后备预案。
3.使用:-XX:+UseSerialOldGC
八、Parallel Old垃圾收集器
1.概念:Parallel Old 收集器是 Parallel Scavenge 的老年代版本,是一个多线程收集器,采用标记-整理算法。可以与 Parallel Scavenge 收集器搭配,可以充分利用多核 CPU 的计算能力。
2.场景:与Parallel Scavenge 收集器搭配使用;注重吞吐量。jdk7、jdk8 默认使用该收集器作为老年代收集器
3.使用:-XX:+UseParallelOldGC
九、CMS(Concurrent Mark Sweep) 垃圾收集器
1.概念:CMS 收集器是一种以最短回收停顿时间为目标的收集器,以 “ 最短用户线程停顿时间 ” 著称。整个垃圾收集过程分为 4 个步骤:
初始标记:标记一下 GC Roots 能直接关联到的对象,速度较快。
并发标记:进行 GC Roots Tracing,标记出全部的垃圾对象,耗时较长。
重新标记:修正并发标记阶段引用户程序继续运行而导致变化的对象的标记记录,耗时较短。
并发清除:用标记-清除算法清除垃圾对象,耗时较长。
2.场景:重视服务器响应速度,要求系统停顿时间最短
3.使用:-XX:+UserConMarkSweepGC
十、G1 垃圾收集器
1.概念:
G1 进行垃圾收集的范围是整个堆内存,它采用 “ 化整为零 ” 的思路,把整个堆内存划分为多个大小相等的独立区域(Region),在 G1 收集器中还保留着新生代和老年代的概念,它们分别都是一部分 Region
步骤也分为4步:
初始标记:标记出 GC Roots 直接关联的对象,这个阶段速度较快,需要停止用户线程,单线程执行。
并发标记:从 GC Root 开始对堆中的对象进行可达新分析,找出存活对象,这个阶段耗时较长,但可以和用户线程并发执行。
最终标记:修正在并发标记阶段引用户程序执行而产生变动的标记记录。
筛选回收:筛选回收阶段会对各个 Region 的回收价值和成本进行排序,根据用户所期望的 GC 停顿时间来指定回收计划(用最少的时间来回收包含垃圾最多的区域,这就是 Garbage First 的由来——第一时间清理垃圾最多的区块),这里为了提高回收效率,并没有采用和用户线程并发执行的方式,而是停顿用户线程。
2.场景:要求尽可能可控 GC 停顿时间;内存占用较大的应用。jdk9 默认使用 G1 收集器
3.使用:-XX:+UseG1GC