Serial收集器
最基础的,最古老的收集器。该收集器是单线程工作的(强调在GC的时候,强制停止其他工作线程,直到GC结束)
直到这里你是否认为,Serial收集器是最早出现的,但是现在看来已经老而无用,食之无味的鸡肋?
但事实却是:是HotSpot运行在客户端模式下默认的新生代收集器。
优点:简单+高效
ParNew收集器
实质上是Serial收集器的多线程并行版本。其他的参数(收集算法,Stop The World,对象分配规则,回收策略)和Serial基本一致。
值得一说:除了Serial收集器外,目前只有ParNew收集器可以和CMS收集器配合使用。
Parallel Scavenge收集器
新生代,基于标记-复制算法实现的,能够并行收集垃圾的多线程收集器。
关注的点:达到可控制的吞吐量
Serial Old收集器
Serial收集器的老年代版本,同样是一个单线程的收集器,使用标记整理算法。
用途:
- JDK5以及之前的版本中与Parallel Scavenge收集器搭配使用
- 作为CMS收集器发生失败时的后备预案。
Parallel Old收集器
Parallel Scavenge收集器的老年代版本,支持多线程并发收集。基于标记-整理算法。
在它出现之前,Parallel Scavenge收集器一直处于尴尬的境地。如果新生代选择使用Parallel Scavenge收集器,那么老年代只能选择Serial Old收集器。但是因为Serial Old在性能上的拖累,Parallel Scavenge并不一定获得吞吐量最大化的效果。
直到Parallel Old的出现,“吞吐量优先”终于有了比较名副其实的组合搭配。在注重吞吐量或者处理器资源较为稀缺的时候,可以优先考虑Parallel Scavenge与Parallel Old组合。
CMS收集器
获取最短回收停顿时间为目标的收集器。基于标记-清除算法实现的。
- 初始标记(标记GC Roots 能直接关联到的对象,速度很快)
- 并发标记(从GC Roots 直接关联到的对象开始,遍历整个对象图的过程;耗时较长,不需要停顿用户线程)
- 重新标记(修正在并发标记阶段,标记产生变动的对象;耗时在初始标记与并发标记的中间)
- 并发清除(清理,此时可以与用户线程并发)
初始标记和重新标记需要“Stop The World”。
优点:
- 并发收集
- 低停顿
缺点:
- CMS收集器对于处理器资源非常敏感。
- 内存碎片
G1收集器
G1收集器开创了收集器面向局部收集的设计思路和基于Region的内存布局形式。
主要是面向服务端应用的垃圾收集器。
它不再坚持固定大小以及固定数量的分代区域划分,而是把连续的Java堆划分为多个大小相等的独立区域。
运作过程:
- 初始标记
- 并发标记
- 最终标记
- 筛选回本
初始标记:标记GC Roots能够关联到的对象。这个阶段需要停顿用户线程,但是耗时很短。并且是借用Minor GC的时候同步完成的。
并发标记:从GC Roots开始对堆中对象进行可达性分析。这段时间较长,但是用户线程可以并发执行。最后要重新处理SATB记录下的在并发时有引用变动的对象。
最终标记:用户线程做短暂的停顿,处理并发阶段结束后遗留的最后少量SATB记录。
筛选回收:更新Region统计数据。排序后回收。此时暂停用户线程。由多条收集器线程并行执行。
各类参数
//激活CMS
-XX:+UseConcMarkSweepGC
//ParNew收集器
-XX:+/-UseParNewGC
//垃圾收集的线程数
-XX:ParallelGCThreads
//控制最大垃圾收集停顿时间
-XX:MaxGCPauseMillis
//设置吞吐量大小
-XX:GCTimeRatio
//垃圾收集的自适应的调节策略
-XX:+UseAdaptiveSizePolicy
//Eden与Survivor区 的比例
-XX:SurvivorRatio
//新生代的大小
-Xmn
//晋升老年代对象大小
-XX:PretenureSizeThreshold
//CMS的触发百分比,降低内存回收频率
-XX:CMSInitiatingOccu-pancyFraction
//