垃圾回收算法是内存回收的理论,垃圾收集器是内存回收的实现。
1.Serial收集器
Serial串行的,这是一个单线程收集器,它的单线程不仅仅是说它只是用一个CPU或一条手机线程去进行内存回收,更重要的是它在工作时会暂停其他所有的工作线程,直到它工作结束。也就是说,Serial收集器工作时,JVM会在用户不可见的情况下在后台把用户的正常工作线程全部停掉,直到它完成工作。
Serial是虚拟机运行在客户端下默认的新生代收集器(使用复制算法)。与其他收集器相比,它简单而且高效。在用户桌面应用场景中,分配给虚拟机的内存不会有多大,因为垃圾收集而停顿的时间完全可以控制在几十毫秒最多一百毫秒以内,只要不频繁发生,这点停顿是可以接受的。因此, Serial收集器是Client端下虚拟机的一个很棒的选择。
2.ParNew收集器
ParNew收集器就是Serial的多线程版本,它使用多个线程进行内存回收工作,此时用户进程暂停。除此以外,ParNew与Serial相比并没有太多创新之处,但他确实Server下虚拟机中的首选新生代收集器,因为只有它才可以与CMS收集器配合工作。
ParNew收集器默认开启的线程数和CPU的数量相同,可以通过-XX:ParallelGCThreads参数来限制来集收集的线程数。
3.Parallel Scavenge收集器
Parallel Scavenge也是一个新生代的收集器,使用复制算法,是并行的多线程收集器,. . . 这些与ParNew 看起来很相似,那么它有什么独特之处呢?
与其他收集器尽可能缩短垃圾收集的停顿时间不同,Parallel Scavenge注重于达到一个可控制的吞吐量, 吞吐量 = CPU处理用户代码的时间 / (运行用户代码的时间 + 垃圾收集的时间)。
停顿时间短的适用于用户交互的程序,良好的响应速度能提升用户的体验;
高吞吐量则可以最高效率的利用CPU时间,尽快的完成程序的运算任务,主要使用与后台不需要太多交互的任务。
4.Serial Old 收集器
Serial Old是Serial的老年代版本, 也是一个单线程的收集器,它使用“标记-整理”算法在老年代进行工作。主要是在Client下的虚拟机上运行。
5.Parallel Old 收集器
Parallel Old 是 Parallel Scavenge 的老年代版本,使用多线程和“标记- 整理”算法回收内存。它的出现使“吞吐量优先”组合有了比较名副其实的应用组合。在此之前,如果新生代选了 Parallel Scavenge收集器,老年代除了 Serial Old没有别的选择(Parallel Scavenge 与 CMS 无法配合工作),由于Serial Old 单线程在服务端的拖累,即使选择 Parallel Scavenge也不一定能提升吞吐量,尤其是老年代很大且硬件比较高级的环境时。
6.CMS收集器
CMS(Concurrent Mark Sweep)收集器是以停顿时间最短为目标,它适用于运行在服务端希望响应速度快的应用。
CMS的工作过程可以分为4部分:
初始标记;并发标记;重新标记;并发清除
初始标记和重新标记时暂停用户进程。
初始标记就是找到与GC Roots 直接相连的对象,速度很快,并发标记就是跟搜索的过程,重新标记就是更正并发标记过程中因执行用户进行而变动的那一部分对象记录,它所耗费的时间远比并发标记短。
总体来说,CMS工作耗时主要在于并发标记和并发清除,因此可以大致看做CMS与用户进程是一起并发执行的。
CMS是老年代的收集器,可惜它不能与新生代的Parallel Scavenge一起工作,因此只能选择Serial或ParNew进行组合了。
CMS的优点:并发收集,低停顿
缺点:
~并发造成对CPU资源的高要求,CMS默认启动的线程数 (CPU数 + 3)/ 4,当CPU在4个以上时,垃圾收集线程占据CPU资源不足25%,当CPU小于4时, 假如CPU为2,那么CMS工作哦时用户程序的速度回忽然降低50%,这就是CMS的弊端。
~CMS无法处理浮动垃圾,CMS并发清除时用户程序仍在执行,会产生垃圾,也就是浮动垃圾,它们只能在下一次清除。同时因为用户程序的并发执行,CMS不能再老年代快满时才进行清除,它需要预留出用户程序的工作区,否则会出现“Concurrent Mode Failure”,这时候JVM临时启用Serial Old,增加了停顿时间。默认CMS在老年代使用68%的空间后被激活工作。
~CMS基于“标记-清除”算法会造成很多内存碎片,不利于大对象的分配。
为了解决这个问题,CMS收集器提供了一个
-XX:+UserCMSCompactAtFullCollection开关参数,可以在Full GC后进行碎片整理,这也相应会增加停顿时间。
7.G1 收集器
G1(Grabge Frist)是当前收集器技术的最前沿成果,与CMS相较,它采用“标记-整理”算法避免产生大量内存碎片,二,它可以非常精准的控制停顿时间。
G1 可以实现基本不牺牲吞吐量的情况下完成低停顿的回收,这是由于它极力避免全区域的垃圾回收,G1将整个Heap分为多个大小固定的Region并跟踪这些区域的垃圾堆积程度,在后台建立一个优先列表,每次根据允许的收集时间优先回收垃圾最多的区域,从而保证了有限时间内可以获得最高的收集效率。