HotSpot JVM收集器
上图有七个垃圾收集器,分为两块,上块儿是新生代收集器,下块儿是老年代收集器。如果俩个收集器之间有连线,就说明他们可以搭配使用
Serial收集器
新生代中的单线程收集器,使用复制算法,是JVM client端的默认收集器。
优点:简单而高效(与其他收集器的单线程相比) 缺点:由于是单线程,进行垃圾收集的时候必须暂停其他线程
ParNew收集器
是Serial收集器的多线程版本,除了使用多线程进行垃圾回收外,其它策略与Serial收集器基本相同
Server模式下虚拟机首选的新生代收集器,除了Serial收集器外,只有它能与CMS收集器相配合
Parallel Scavenge收集器
新生代收集器,使用复制算法,并行的多线程收集器
Parallel Scavenge收集器关注点不是缩短用户线程的停顿时间,关注于达到一个可控制得吞吐量(Throughput);吞吐量:吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)
停顿时间越短关于于与用户交互,高吞吐量则为了高效的利用cpu时间,主要适合后台运算而不需要太多的交互任务
Serial Old收集器
Serial收集器的老年代版本,是单线程收集器,使用“标记-整理”算法,在client端的JVM中使用
用途:作为CMS收集器的后备选案
Parallel Old收集器
Parallel Scavenge收集器的老年代版本,使用多线程和“整理-标记”算法
在注重吞吐量及CPU资源敏感的场合,都可以优先考虑Parallel Scavenge加Parallel Old收集器
CMS收集器(Concurrent Mark Sweep)
目的:获取最短回收停顿时间,重视服务的响应速度,基于“标记-清除”算法
过程有4个步骤:
1.初始标记(CMS initial mark)
2.并发标记(CMS concurrent mark)
3.重新标记(CMS remark)
4.并发清除(CMS concurrent sweep)
其中,初始标记,重新标记这两个步骤需要“STOP - THE - WORLD”。初始标记仅仅是标记GC Roots能直接关联到的对象,速度很快,并发标记阶段就是进行GC Tracing的过程,而重新标记阶段则是为了修正并发标记期间,因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录。
总体来说,是与用户线程并发执行的。
主要优点:并发收集,低停顿
缺点:
即需要预留足够的内存空间给用户线程使用,因此CMS收集器不能像其他收集器那样等到老年代几乎完全被填满了再进行收集,需要预留一部分内存空间提供并发收集时的程序运作使用。在默认设置下,CMS收集器在老年代使用了68%的空间时就会被激活,也可以通过参数-XX:CMSInitiatingOccupancyFraction的值来提供触发百分比,以降低内存回收次数提高性能。要是CMS运行期间预留的内存无法满足程序其他线程需要,就会出现“Concurrent Mode Failure”失败,这时候虚拟机将启动后备预案:临时启用Serial Old收集器来重新进行老年代的垃圾收集,这样停顿时间就很长了。所以说参数-XX:CMSInitiatingOccupancyFraction设置的过高将会很容易导致“Concurrent Mode Failure”失败,性能反而降低。
G1收集器
垃圾收集器参数总结
-XX:+<option> 启用选项-XX:-<option> 不启用选项-XX:<option>=<number>-XX:<option>=<string>
参数 描述 -XX:+UseSerialGC
Jvm运行在Client模式下的默认值,打开此开关后,使用Serial + Serial Old的收集器组合进行内存回收 -XX:+UseParNewGC 打开此开关后,使用ParNew + Serial Old的收集器进行垃圾回收 -XX:+UseConcMarkSweepGC 使用ParNew + CMS + Serial Old的收集器组合进行内存回收,Serial Old作为CMS出现“Concurrent Mode Failure”失败后的后备收集器使用。 -XX:+UseParallelGC Jvm运行在Server模式下的默认值,打开此开关后,使用Parallel Scavenge + Serial Old的收集器组合进行回收
-XX:+UseParallelOldGC 使用Parallel Scavenge + Parallel Old的收集器组合进行回收
-XX:SurvivorRatio 新生代中Eden区域与Survivor区域的容量比值,默认为8,代表Eden:Subrvivor = 8:1 -XX:PretenureSizeThreshold 直接晋升到老年代对象的大小,设置这个参数后,大于这个参数的对象将直接在老年代分配 -XX:MaxTenuringThreshold 晋升到老年代的对象年龄,每次Minor GC之后,年龄就加1,当超过这个参数的值时进入老年代 -XX:UseAdaptiveSizePolicy 动态调整java堆中各个区域的大小以及进入老年代的年龄 -XX:+HandlePromotionFailure 是否允许新生代收集担保,进行一次minor gc后, 另一块Survivor空间不足时,将直接会在老年代中保留 -XX:ParallelGCThreads 设置并行GC进行内存回收的线程数 -XX:GCTimeRatio GC时间占总时间的比列,默认值为99,即允许1%的GC时间,仅在使用Parallel Scavenge 收集器时有效 -XX:MaxGCPauseMillis 设置GC的最大停顿时间,在Parallel Scavenge 收集器下有效 -XX:CMSInitiatingOccupancyFraction 设置CMS收集器在老年代空间被使用多少后出发垃圾收集,默认值为68%,仅在CMS收集器时有效,-XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSCompactAtFullCollection
由于CMS收集器会产生碎片,此参数设置在垃圾收集器后是否需要一次内存碎片整理过程,仅在CMS收集器时有效 -XX:+CMSFullGCBeforeCompaction
设置CMS收集器在进行若干次垃圾收集后再进行一次内存碎片整理过程,通常与UseCMSCompactAtFullCollection参数一起使用 -XX:+UseFastAccessorMethods
原始类型优化 -XX:+DisableExplicitGC
是否关闭手动System.gc -XX:+CMSParallelRemarkEnabled
降低标记停顿 -XX:LargePageSizeInBytes
内存页的大小不可设置过大,会影响Perm的大小,-XX:LargePageSizeInBytes=128m
Client、Server模式默认GC
新生代GC方式 老年代和持久代GC方式 Client
Serial 串行GC Serial Old 串行GC Server Parallel Scavenge 并行回收GC Parallel Old 并行GC
Sun/oracle JDK GC组合方式
新生代GC方式 老年代和持久代GC方式 -XX:+UseSerialGC
Serial 串行GC Serial Old 串行GC -XX:+UseParallelGC Parallel Scavenge 并行回收GC Serial Old 并行GC -XX:+UseConcMarkSweepGC ParNew 并行GC CMS 并发GC
当出现“Concurrent Mode Failure”时
采用Serial Old 串行GC-XX:+UseParNewGC ParNew 并行GC Serial Old 串行GC -XX:+UseParallelOldGC Parallel Scavenge 并行回收GC Parallel Old 并行GC -XX:+UseConcMarkSweepGC
-XX:+UseParNewGC
Serial 串行GC CMS 并发GC
当出现“Concurrent Mode Failure”时
采用Serial Old 串行GC