HotSpot jvm收集器
上面有7中垃圾收集器,上面的是新生代垃圾收集器,下面为老年代垃圾收集器,G1收集器收集范围在整个
新生代和老年代,连线的收集器表示两个收集器可以搭配使用.
首先说明:
并行(Parallel):指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态。
并发(Concurrent):指用户线程与垃圾收集线程同时执行(但不一定是并行的,可能会交替执行),
用户程序在继续运行,而垃圾收集程序运行于另一个CPU上。
1.Serial收集器(串行GC)
Serial收集器,顾名思义,这个收集器是单线程收集器,他单线程的意思有两点,一是只会使用
一个cpu或者一个线程去执行垃圾收集的动作,二是在垃圾收集的时候需要停止其他的所有工作线程
(stop the world 以下STW).该收集器现在作为client端默认的收集器.该垃圾收集器使用的垃圾回
收算法:复制算法.
2.ParNew收集器(并行GC)
Serial收集器的多线程版本,该垃圾收集器使用多个线程去执行垃圾收集. 和Serial收集器相
比较而言,一随着Cpu数量上升,ParNew收集器性能越来越高于Serial收集器.二ParNew在需要server
端的虚拟机中作为默认垃圾收集器.回收算法同Serial收集器.
3.Prallel Scavenge收集器(并行回收GC)
Prallel Scavenge收集器和ParNew收集器一样,使用同样的垃圾回收算法,同样使用多个线程
去执行垃圾收集. 和CMS垃圾收集器关注垃圾收集时间不同的是,Prallel Scavenge收集器主要关注点
是在吞吐量(吞吐量= 程序运行时间/(程序运行时间+垃圾回收时间)),所以Pra Scavenge收集器使用
场景是在后台计算不需要太多用户交互的地方.该收集器可以设置垃圾收集时间和吞吐量给虚拟机,虚拟
机会自适应的调整.自适应调节也是该收集器和ParNew收集器一个重要的区别.
4.Serial Old收集器(串行GC)
Serial Old是Serial收集器的老年代版本,同样使用单线程去执行,主要使用在client端,如果
使用在server端,一般作为cms的后备方案,使用标记整理算法.
5.Parallel Old收集器(并行GC)
Parallel Old收集器是Parallel Scavenge收集器的老年代版本,使用多线程去执行使用标记
整理算法.
6.CMS收集器(并发GC)
CMS收集器是一种以获取最短停顿时间为目标的垃圾收集器,CMS是基于标记清除算法实现的,整
个垃圾收集的过程分为4个过程.
1.初始标记
2.并发标记
3.重新标记
4.并发清除
CMS收集器虽然是并发GC的,但是还是有停顿
时间的,在初始标记和重新标记的过程还是需要停顿其他用户线程(STW),初始标记是标记处GC ROOTS
能直接关联到的对象,速度很快,并发标记阶段是进行GC ROOTS 根搜索算法阶段,判定对象是否存活.
重新标记阶段是修正并发期间由于用户程序运行导致标记产生变动的那一部分对象的标记记录.在这个
四个阶段耗时最长的阶段是并发标记和并发清除阶段,这两个阶段都是可用户线程一起工作,所以从整体
上来看,CMS收集器垃圾回收的过程 和用户线程是并发执行的.
CMS有点就是停顿时间短,但是还有有以下几个缺点:
1.CMS收集器对cpu非常敏感,并发执行不会让用户线程停顿,但是在收集过程中需要占用cpu资源,导致
应用程序变慢,吞吐量变小.
2.由于在并发清除阶段是并发执行的,所以在并发清除阶段产生的垃圾不能被清除,只能放在下次GC是在
清除,这部分的垃圾称之为"浮动垃圾".
3.在并发清除阶段由于程序还要继续执行,需要预留一部分空间以供使用,所以不能像其他的收集器一样
等到老年代满了在收集垃圾,默认情况下在老年代使用到达68%时激活垃圾回收,如果在垃圾回收的过程
中,发生老年代空间不够用的时候,会发生Concurrent Mode Failure,这个时候虚拟机就会启用备用方案,
Serial Old收集器来重新对老年代来收集,但是这个时候停顿时间就更长了.
4.还有个问题就是CMS收集器是基于标记清除算法的,所以会有空间碎片过多的问题,当有大的对
象需要分配的时候,可能会发生FULL GC.所以CMS收集器默认设置了每当FULL GC的时候开启内存碎片
整理合并的过程,这样碎片的问题就被解决了,但是停顿时间就边长了.所以提供了一个参数
-XX:CMSFullGCsBeforeCompaction,这个参数是用于设置执行多少次不压缩的Full GC后,跟着来
一次带压缩的(默认值为0,表示每次进入Full GC时都进行碎片整理).
7.G1收集器(并发GC)
分代收集:与其他收集器一样,分代概念在G1中依然得以保留。 虽然G1可以不需要其他收集器配
合就能独立管理整个GC堆,但它能够采用不同的方式去处理新创建的对象和已经存活了一段时间、 熬
过多次GC的旧对象以获取更好的收集效果。
空间整合:与CMS的“标记—清理”算法不同,G1从整体来看是基于“标记—整理”算法实现的收集器,
从局部(两个Region之间)上来看是基于“复制”算法实现的,但无论如何,这两种算法都意味着G1运
作期间不会产生内存空间碎片,收集后能提供规整的可用内存。 这种特性有利于程序长时间运行,分
配大对象时不会因为无法找到连续内存空间而提前触发下一次GC。
可预测的停顿:这是G1相对于CMS的另一大优势,降低停顿时间是G1和CMS共同的关注点,但G1
除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为M毫秒的时间
片段内,消耗在垃圾收集上的时间不得超过N毫秒,这几乎已经是实时Java(RTSJ)的垃圾收集器的特
征了。在G1之前的其他收集器进行收集的范围都是整个新生代或者老年代,而G1不再是这样。 使用G1
收集器时,Java堆的内存布局就与其他收集器有很大差别,它将整个Java堆划分为多个大小相等的独
立区域(Region),虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,它
们都是一部分Region(不需要连续)的集合。G1收集器之所以能建立可预测的停顿时间模型,是因为
它可以有计划地避免在整个Java堆中进行全区域的垃圾收集。 G1跟踪各个Region里面的垃圾堆积的价
值大小(回收所获得的空间大小以及回收所需时间的经验值),在后台维护一个优先列表,每次根据允
许的收集时间,优先回收价值最大的Region(这也就是Garbage-First名称的来由)。 这种使用Region
划分内存空间以及有优先级的区域回收方式,保证了G1收集器在有限的时间内可以获取尽可能高的收
集效率。
一些垃圾回收常见参数设置: