主要GC区域在堆,一共有7种垃圾回收器。堆的GC区域主要分为老年代和新生代。
其中新生代独有GC机制有三种,分别是:Serial[ˈsɪəriəl]新生代串行、ParNew新生代并行、Parallel Scavenge(拍了sanvwnge)新生代并行。
-
Serial收集器是发展历史最悠久的垃圾收集器,是一个单线程的收集器,在进行垃圾收集时会STW停掉其他所有线程直到垃圾回收结束。
-
ParNew回收器也会暂停所有用户线程,但是会开启多个线程执行垃圾回收,可以手动设置执行垃圾回收的线程数,如果不指定老年代回收器种类,现在默认是和和老年代串行一起使用,但是将来会删除,所以这里会有一个警告。
-
Parallel Scavenge收集器也是一个新生代并行收集器,它和ParNew的最大区别就是它有自适应调节策略,会根据当前系统运行情况,动态调整最合适的垃圾回收时间或最大吞吐量。吞吐量越高意味着cpu执行效率越高,这种可以动态调整最大吞吐量的收集器多适用与后台不需要过多交互的任务。
老年代独有的垃圾回收机制有三种,分别是:Serial Old老年代串行、Parallel Old老年代并行、CMS老年代并发。
-
Serial Old收集器现在很少使用,主要是给其他两种收集器做辅助用的,在它们挂掉时顶上去;
-
Parallel Old收集器在jdk6之后才开始提供,使用的是标记整理算法。之前新生代Parallel Scavenge只能和老年代Serial Old一起搭配使用,无法保证整体的吞吐量;CMS是一种gc线程可以和用户线程并发进行的机制。它的垃圾回收过程主要分为四步:第一步初始标记,就是标记GC Root可以直接关联的对象,也就是不需要清理的对象,这一步也会暂停用户线程,但是耗时非常短。第二步并发标记,会标记全部对象,这一步会和用户线程一起工作。第三步是重新标记,这一步会暂停用户线程,因为它需要标记和用户线程共同工作期间用户线程运行而导致标记发生变动的那些对象。第四步是并发清除,直接清除之前标记的需要清理的对象,和用户线程一起工作。
-
CMS是G1出现之前大型应用首选的垃圾回收器。它的缺点是比较占用内存会产生大量碎片,而且如果在堆内存用完之前没有完成垃圾回收,就会触发担保机制,老年串行收集器以stw的形式进行一次GC。
还是一种java7发布的两者都可以使用的垃圾回收机制,G1收集器,它是把老年代和新生代一起划分为多个固定的大小区域region,默认是2048个,每个region从1M到32M不等,每次根据允许停顿的时间去收集垃圾最多的区域。它和CMS相比,在清理的同时会进行整理,因此不会产生很多内存碎片,而且它在停顿时间上加了预测机制,减少了垃圾收集停顿的时间。
老年代和新生代的垃圾收集器是有固定搭配的,不能胡乱搭配。新生代serial对应Serial Old(MSC),新生代ParNew对应老年代CMS(老年代并发),新生代Parallel Scavenge对应老年代Parallel Old(也可以搭配 Serial Old)
新生代的垃圾收集器用的都是复制算法,老年代只有CMS使用的是标记清除算法,其他都是标记整理算法。G1用的是也是标记整理