垃圾回收器大致分为三类:串行回收器、吞吐量优先回收器和响应时间优先回收器。
一 串行回收器
串行回收器:采用单线程进行垃圾回收,适合堆内存较小的场景。有Serial回收器和SerialOld回收器,Serial回收器采用复制算法对新生代进行垃圾回收,SerialOld回收器采用标记整理算法对老年代进行回收。串行回收器,在执行GC过程中会造成用户线程阻塞,也就是STW问题。
jvm参数配置:
//-XX:+UseSerialGC = Serial + SerialOld -XX:+UseSerialGC二 吞吐量优先回收器
吞吐量优先回收器:吞吐量优先回收器采用多线程并行进行垃圾回收,需要多核CPU才能发挥其能力,适合堆内存大的场景。它的特点是单位时间内,执行垃圾回收的时间最短,也就是单位时间内产生STW时间最短。这是JDK8默认采用的回收器,有Paralle回收器和ParalleOld回收器,Paralle回收器采用复制算法对新生代进行垃圾回收,ParalleOld垃圾回收器采用标记整理算法对老年代进行回收。可以通过参数配置并行执行垃圾回收的线程数,默认是CPU核数,也可以通过参数设置动态调整堆内存的大小,还可以配置单位时间内垃圾回收的时间最大占比,以及单次执行GC的最长时间。吞吐量优先回收器,在GC过程会产生STW问题。
jvm参数配置:
//配置如下两项中的一项即可 -XX:+UseParallelGC 或 -XX:+UseParallelOldGC
//动态调整堆内存大小 -XX:+UseAdaptiveSizePolicy //单位时间内GC时间占比 -XX:GCTimeRatio=ratio //gc执行的最大时间 -XX:MaxGCPauseMillis=ms //并行执行GC的线程数,默认是CPU核数 -XX:ParallelGCThreads=n三 响应时间优先回收器
响应时间优先回收器:响应时间优先回收器,采用多线程并发进行垃圾回收,适合堆内存较大的场景。它的特点是单次执行GC的时间最短,也就是单次执行GC STW时间最短。它包含ParNew回收器和ConcMarkSeep回收器也就是CMS回收器,ParNew回收器采用复制算法对新生代进行回收,CMS回收器采用标记清理算法对老年代进行回收。CMS回收器在一些阶段采用了垃圾回收线程与用户线程并发执行,产生的STW时间较短,它的执行过程是这样:在初始标记阶段,用户线程被阻塞,由于只对一些根对象进行标记,时间很短,很快就进入了并发阶段,在并发阶段用户线程恢复执行,与垃圾回收线程并发执行,然后进入重新标记阶段,重新标记阶段用户线程被阻塞,只有多个垃圾回收线程并行运行,最后进入并发清理过程,在这个过程用户线程恢复执行,与垃圾回收线程并发执行,在这个过程用户线程可能会创建新的对象,我们称之为浮动垃圾,由于存在浮动垃圾,不可以内存满了才进行垃圾回收,可以通过参数配置内存占用百分之多少时进行垃圾回收,可以通过参数配置多个垃圾回收线程并行执行的数量,默认是CPU核数,还可以配置有多少个垃圾回收线程与用户线程并发执行,建议配置为并行执行线程数的1/4,还可以通过参数配置在使用CMS回收器回收时进行一次Minor GC,减少标记时扫描的对象。最后CMS回收器有一定弊端,由于它采用了标记清理算法,存在内存碎片,当对象分配不下时,CMS回收器会退化为SerialOld回收器,它是采用单线程对老年代采用标记整理算法进行回收,执行速度慢。
jvm参数配置:
UseConcMarkSweepGC 老年代回收器,UseParNewGC 新生代回收器,在一些条件UseConcMarkSweepGC会退化为SerialOld回收器 -XX:+UseConcMarkSweepGC ~ -XX:+UseParNewGC ~ SerialOld
//并行执行的线程数,如在重新标记阶段有多少个gc线程,默认是cpu核数 -XX:ParallelGCThreads=n //并发进行gc的线程数,与用户线程同时运行时如并发标记阶段或并发清理阶段有多少个gc线程,建议为并发线程设置的1/4 -XX:ConcGCThreads=threads //老年代内使用占比多少进行gc -XX:CMSInitiatingOccupancyFraction=percent //在进行cms回收器回收前进行一次minor gc -XX:+CMSScavengeBeforeRemark



