JAVA的跨平台性决定了其部署的服务器类型各异,其内存结构也是大不相同的。因此针对不同的内存结构适用于不同的垃圾收集策略。因此也需要各种各样的垃圾收集器来满足需求。接下来,我们介绍下市场上主流的几个垃圾收集器。
一、Serial收集器
特点:
1、最基本、发展最悠久
2、单线程垃圾收集器
要理解单线程垃圾收集器,可以举例如下图所示。从图中我们可以看出,当JVM需要进行垃圾回收时候,需要将正在运行的所有线程全部终止才可以。
用途:
客户端场景使用。因为客户端分配内存少,收集过程很快,且可以减少线程开销.
二、parnew收集器
ParNew收集器是JAVA虚拟机中垃圾收集器的一种。它是Serial收集器的多线程版本,除了使用多条线程进行垃圾收集之外,其余行为包括Serial收集器可用的所有控制参数(例如:-XX:SurvivorRatio、-XX:PretenureSizeThreshold、-XX:HandlePromotionFailure等)、收集算法、Stop The World、对象分配规则、回收策略等都与Serial收集器一致。
ParNew是许多运行在Server模式下的虚拟机中首选的新生代收集器,在JDK1.6以及之前的版本中,除了Serial收集器外,只有它能与CMS收集器配合工作。
在JDK 1.5时期,HotSpot推出了一款在强交互应用中几乎可称为有划时代意义的垃圾收集器—CMS收集器(Concurrent Mark Sweep,本节稍后将详细介绍这款收集器),这款收集器是HotSpot虚拟机中第一款真正意义上的并发(Concurrent)收集器,它第一次实现了让垃圾收集线程与用户线程(基本上)同时工作,用前面那个例子的话来说,就是做到了在你妈妈打扫房间的时候你还能同时往地上扔纸屑。
所以在JDK 1.5中使用CMS来收集老年代的时候,新生代只能选择ParNew或Serial收集器中的一个。ParNew收集器也是使用 -XX:+UseConcMarkSweepGC选项后的默认新生代收集器,也可以使用 -XX:+UseParNewGC选项来强制指定它。
三、parallel Scavenge收集器
Parallel Scavenge收集器是Java虚拟机中垃圾收集器的一种。又称为吞吐量优先收集器,和ParNew收集器类似,是一个新生代收集器。使用复制算法的并行多线程收集器。而且是并行的多多线程收集器。java1.8默认的收集器就是parallel Scavenge。
Parallel Scavenge收集器的关注点与其他收集器不同, ParallelScavenge收集器的目标则是达到一个可控制的吞吐量(Throughput)
吞吐量 = 运行用户代码时间/(运行用户代码时间+垃圾收集时间)
为了实现吞吐量的可控,parallel Scavenge收集器提供了三个重要参数。
1、控制最大垃圾收集停顿时间的-XX:MaxGCPauseMillis参数
MaxGCPauseMillis参数允许的值是一个大于0的毫秒数,收集器将尽力保证内存回收花费的时间不超过设定值。不过大家不要异想天开地认为如果把这个参数的值设置得稍小一点就能使得系统的垃圾收集速度变得更快,GC停顿时间缩短是以牺牲吞吐量和新生代空间来换取的:系统把新生代调小一些,收集300MB新生代肯定比收集500MB快吧,这也直接导致垃圾收集发生得更频繁一些,原来10秒收集一次、每次停顿100毫秒,现在变成5秒收集一次、每次停顿70毫秒。停顿时间的确在下降,但吞吐量也降下来了。
2、直接设置吞吐量大小的 -XX:GCTimeRatio参数。
GCTimeRatio参数的值应当是一个大于0小于100的整数,也就是垃圾收集时间占总时间的比率,相当于是吞吐量的倒数。如果把此参数设置为19,那允许的最大GC时间就占总时间的5%(即1 /(1+19)),默认值为99,就是允许最大1%(即1 /(1+99))的垃圾收集时间。
3、UseAdaptiveSizePolicy开关参数。
-XX:+UseAdaptiveSizePolicy是一个开关参数,当这个参数打开之后,就不需要手工指定新生代的大小(-Xmn)、Eden与Survivor区的比例(-XX:SurvivorRatio)、晋升老年代对象年龄(-XX:PretenureSizeThreshold)等细节参数了,虚拟机会根据当前系统的运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或最大的吞吐量,这种调节方式称为GC自适应的调节策略(GC Ergonomics)。
自适应调节策略:
除过上述参数外,Parallel Scavenge收集器还能够配合自适应调节策略,把内存管理的调优任务交给虚拟机去完成。只需要把基本的内存数据设置好(如-Xmx设置最大堆),然后使用MaxGCPauseMillis参数(更关注最大停顿时间)或GCTimeRatio参数(更关注吞吐量)给虚拟机设立一个优化目标,那具体细节参数的调节工作就由虚拟机完成了。自适应调节策略也是Parallel Scavenge收集器与ParNew收集器的一个重要区别。
四、cms收集器(Concurrent Mark-Sweep)
CMS是一个并发收集器,用于收集老年代内存。
工作过程:
1. 初始标记(CMS-initial-mark) ,会导致swt;
标记老年代中所有的GC Roots对象
2. 并发标记(CMS-concurrent-mark),与用户线程同时运行;
从“初始标记”阶段标记的对象开始找出所有存活的对象;
3. 预清理(CMS-concurrent-preclean),与用户线程同时运行;
4. 可被终止的预清理(CMS-concurrent-abortable-preclean) 与用户线程同时运行;
5. 重新标记(CMS-remark) ,会导致swt;
6. 并发清除(CMS-concurrent-sweep),与用户线程同时运行;
7. 并发重置状态等待下次CMS的触发(CMS-concurrent-reset),与用户线程同时运行;
cms运行流程图如下所示:
五、G1集器
G1收集器从2004年SUN发表的第一篇G1论文发展至今,现在已经号称最牛的JAV收集器。
G1收集器详细内容可参考下方博客。
作者:coderlius
来源:CSDN
原文:https://blog.csdn.net/coderlius/article/details/79272773