垃圾收集器
如果说收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现。
Serial收集器:
Serial(串行)收集器是一个单线程的收集器,单线程一方面意味着它 只会使用一个CPU或者一条线程去完成垃圾收集工作,另一方面也意味着它进行垃圾收集时必须暂停其他线程的所有工作(“Stop The Word”),直到它收集结束为止。(通过配置-XX:+UseSerialGC 可在新生代使用Serial收集器, 配置 -XX:+UseSerialOldGC可在老年代使用Serial收集器)
ParNew收集器(-XX:UseParNewGC):
ParNew收集器其实就是Serial收集器的多线程版本,除了使用多线程进行垃圾收集外,其余行为和Serial收集器完全一样。默认的收集线程数跟CPU核数相同,也可以使用参数(-XX:ParallelGCThreads)指定线程收集数,但一般不推荐修改。(ParNew收集器一般与CMS收集器搭配使用,ParNew收集器用在新生代,CMS收集器用在老年代)
Parallel Scavenge收集器(-XX:+UseParallelGC(年轻代) -XX:+UseParallelOldGC(老年代))
Parallel Scavenge收集器类似于ParNew收集器,是Server模式(内存大于2G,2个CPU)下的默认收集器。它的关注点是吞吐量(高效率的利用CPU)。吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)
CMS收集器(-XX:+UseConcMarkSweepGC(老年代))
CMS(Conrrurent Mark Sweep)收集器是以获取最短回收停顿时间为目标的收集器。它非常符合在注重用户体验的应用上使用,它是HotSpot虚拟机第一款真正意义上的并发收集器,它第一次实现了让垃圾收集线程与用户线程(基本上)同时工作。
优点:并发收集、低停顿
缺点:
对CPU资源敏感(会和服务器抢资源)
无法处理浮动垃圾(在并发清理阶段又产生垃圾,这种浮动垃圾只能等到下一次GC再清理了)
它使用的回收算法“标记-清除”算法会导致收集结束时会有大量空间碎片产生,当然通过参数-XX:+UseCMSCompactAtFullCollection可以让JVM在执行完标记-清除后再做整理。
执行过程中的不确定性。会存在上一次垃圾回收还没执行完,然后垃圾回收又被触发的情况,特别是在并发标记和并发清理阶段出现,一百回收,系统以便运行,也许没回收完就再次触发Full GC,也就是“concurrent mode failure”,此时会进行入“Stop The Word”,用Serial Old垃圾收集器来回收。
相关参数:
-XX:+UseConcMarkSweepGC:启动CMS
-XX:ConcGCThreads:并发的GC线程数
-XX:+UseCMSCompactAtFullCollection:full GC之后做压缩整理(减少碎片)
-XX:CMSFullGCsBeforeCompaction:多少次full GC之后压缩一次,默认是0,代表每次full GC之后都会压缩一次。
-XX:CMSInitiatingOccupancyFraction:当老年代使用达到该比例时会触发full GC(默认是92,这是百分比)
-XX:+UseCMSInitiatingOccupancyOnly:只使用设定的回收阈值(-XX:CMSInitiatingOccupancyFraction设定的值),如果不指定,JVM在第一次使用设定值,后续则会自动调整。
-XX:+CMSScavengeBeforeRemark:在CMS GC前启动一次minor GC,目的在于减少老年代对年轻代的引用,降低CMS GC在标记阶段的开销,一般MCS的GC耗时80%都在标记阶段。
G1收集器(-XX:+UseG1GC):
G1(Garbage-First)是一款买你选哪个服务器的垃圾收集器,主要针对配备多颗处理器以及大容量内存的机器,以及高概率满足GC停顿时间要求的同时,还具备高吞吐量性能特征。
G1收集器一次GC的运作过程大致分为以下几个步骤:
初始标记(initial mark STW):暂停所有的其他线程,并记录下GC Roots直接能引用的对象,速度很快。
并发标记(Concurrent Marking):同CMS的并发标记。
最终标记(Remark,STW):同CMS的重新标价。
筛选回收(Cleanup,STW):筛选回收阶段首先对各个Region的回收价值和成本进行排序,根据用户所期望的GC停顿时间(可以用JVM参数-XX:MaxGCPauseMillis指定)来定制回收计划。