1、串行收集器
优点:稳定、效率高
缺点:单线程,多核处理器无法展示效果
开启:-XX:+UseSerialGC
开启后新生代和老年代使用串行回收
新生代使用的是复制算法
老年代是使用标记-压缩算法
2、并行收集器
(1)parNew收集器
开启:-XX:+UseParNewGC
此参数影响新生代,开启后新生代会使用并行收集器,老年代会使用串行收集器
新生代使用的是复制算法
是多线程的手机方式,可以使用-XX:ParallelGCThreads限制线程数
(2)Parallel收集器
新生代使用复制算法
老年代使用标记-压缩算法
-XX:+UseParallelGC
使用Parallel收集器+老年代串行
-XX:+UseParallelOldGC
使用Parallel收集器+并行老年代
-XX:MaxGCPauseMills
gc时最大的停顿时间,单位是毫秒。gc会尽力保证回收时间不超过设定值
-XX:GCTimeRatio
取值0-100
垃圾收集时间占总时间比
默认值99,即最大允许1%的时间来做GC
这两个参数是矛盾的,
-XX:MaxGCPauseMills是控制时间的,如果要讲减少每次gc的时间,那么就需要增加gc的次数,增加了gc的次数会影响到系统的整体性能;
-XX:GCTimeRatio这个参数如果比值比较大,那么可以减少了gc的次数,确保系统的整体稳定性,但是每次gc的时间久会增加
3、CMS收集器
使用的是并发标记清除算法(此处的并发指的是可以和用户线程一起执行)
老年的收集器(新生代使用ParNew)
-XX:+UseConcMarkSweepGC
运行过程:
1、初始标记:从根对象开始直接管理到的对象,快速执行,会独占CPU
2、并发标记:会去扫描全局的对象,标记出垃圾对象,是和用户线程一起执行的,此处会降低系统的吞吐量;用标记清除的算法
3、重新标记:由于用户线程在执行的是会产生新的对象,所以在正式清理之前,会再次修正标记,会独占CPU,系统会停顿
4、并发处理:基于标记的对象直接清理,和用户线程一起执行。
特点:
尽可能降低停顿,会影响系统整体吞吐量和性能,并且由于和用户线程 一起执行,导致清理会不彻底
由于用户线程一起执行,不能在空间快满的时候再清理,CMS收集器不想串行和并行收集器在会回收的时候应用程序是停止的,即使堆满了也没有关系;
CMS收集器是和用户线程一起执行的,如果在空间快满的时候启动gc,然后用户线程此时需要申请大量内存,就会导致gc失败,会抛出concurrent mode failure
可以使用+XX:CMSInitiatingOccupancyFraction来设置触发gc的阈值,默认是68
标记清除和标记压缩的区别?
标记清除是直接在内存中将垃圾对象标记出来清理掉,这样会产生内存碎片,可能导致无法分配类似数组等连续空间
标记压缩是首先将可用对象移动到内存的一端,然后清除垃圾对象,这样可用对象是连续的,没有内存碎片
串行和并行回收器在执行的时候独占cpu的,所以是使用标记压缩算法,这样能够确保内存对象不出现碎片问题,合理有效的分配内存资源,
CMS回收器由于要考虑和用户线程并行执行,如果使用标记压缩算法,当对象被移动到一端的时候,会导致用户线程找不到对象,所以使用的是标记清除算法
-XX:+ UseCMSCompactAtFullCollection 在Full GC后,进行一次整理
整理过程是独占的,会引起停顿时间变长
-XX:+CMSFullGCsBeforeCompaction
设置进行几次Full GC后,进行一次碎片整理
-XX:ParallelCMSThreads
设定CMS的线程数量,即回收的时候使用的线程数,约等于cpu的数量,不宜过大