JVM读书笔记之垃圾收集器

本文详细介绍了Java虚拟机中的各种垃圾回收器,包括串行、并行及CMS等多种类型的收集器,并探讨了它们的工作原理、特点及适用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       如果说收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现。Java虚拟机规范中对垃圾收集器应该如何实现并没有任何规定,因此不同的厂商、不同版本的虚拟机所提供的垃圾收集器都可能会有很大差别,并且一般都会提供参数供用户根据自己的应用特点和要求组合出各个年代所使用的收集器。这里讨论的收集器基于JDK 1.7 Update 14之后的HotSpot虚拟机 (在这个版本中正式提供了商用的G1收 集 器 ,之前G1仍处于实验状态 )。下面对几种收集器进行详细介绍。

      1. Serial收集器(串行GC)

          Serial收集器是最基本,历史最悠久的收集器,是一个单线程的收集器。“单线程”的意义不仅仅是说明它只会用一个CPU或单线程进行收集工作,更重要的是在收集过程中必须暂停其他所有工作线程(“stop the world”),直到收集结束。
                    

       实际上到现在为止,它依然是虚拟机运行在Client模式下的默认新生代收集器。 它也有着优于其他收集器的地方:简单而高效(与其他收集器的单线程比),对于限定单个CPU的环境来说,Serial收集器由于没有线程交互的开销,专心做垃圾收集自然可以获得最高的单线程收集效率。在用户的桌面应用场景中,分配给虚拟机管理的内存一般来说不会很大 ,收集几十兆甚至一两百兆的新生代(仅仅是新生代使用的内存,桌面应用基本上不会再大了 ) ,停顿时间完全可以控制在几十毫秒最多一百多毫秒以内 ,只要不是频繁发生 ,这点停顿是可以接受的。所 以 ,Serial收集器对于运行在Client模式下的虚拟机来说是一个很好的选择。

        2. ParNew收集器 (并行GC)

        

       它是运行在Server模式下虚拟机的首选新生代收集器有一个与性能无关但很重要的原因是,除了Serial收集器外,目前只有它能与CMS收集器配合工作。

        3. Parallel Scavenge

           Parallel Scavenge是并行多线程的新生代收集器,采用复制算法收集。Parallel Scavenge收集器关注的目标是达到一个可控制的吞吐量(吞吐量 = 用户代码运行时间/(用户代码运行时间+垃圾收集时间)),其他收集器关注于尽可能缩短垃圾回收时用户线程的暂停时间。停顿时间越短就越适合需要与用户交互的程序,良好的响应速度能提升用户体验,而高吞吐量则可以高效率地利用CPU时间 ,尽快完成程序的运算任务,主要适合在后台运算而不需要太多交互的任务Parallel Scavenge收集器无法与CMS收集器配合工作。


       4. Serial Old收集器

            Serial的老年代版本,也是单线程收集器,采用标记-清理算法。主要是被Client模式下的虚拟机使用。

            

      5. Parallel Old收集器

         Parallel Old是Parallel Scavenge收集器的老年代版本,使用多线程和“标记-整理”算法。这个收集器是在JDK 1.6中才开始提供的,在此之前,新生代的Parallel Scavenge收集器一直处于比较尴尬的状态。原因是 ,如果新生代选择了Parallel Scavenge收集器 ,老年代除了 Serial Old ( PS MarkSweep ) 收集器外别无选择(还记得上面说过Parallel Scavenge收集器无法与CMS收集器配合工作吗)。由于老年代Serial Old收集器在服务端应用性能上的“拖累” ,使用了Parallel Scavenge收集器也未必能在整体应用上获得吞吐量最大化的效果,由于单线程的老年代收集中无法充分利      用服务器多CPU的处理能力,在老年代很大而且硬件比较高级的环境中,这种组合的吞吐量甚至还不一定有ParNew加CMS的组合“给力”。

        直到Parallel Old收集器出现后,“吞吐量优先”收集器终于有了比较名副其实的应用组合,在注重吞吐量以及CPU资源敏感的场合,都可以优先考虑Parallel Scavenge加Parallel Old 收集器。
         

            ParNew收集器就是Serial收集器的多线程版本,除了使用多线程收集之外,其余行为(参数设置,收集算法,stop world,对象分配规则,回收策略等)都一致。

      6. CMS(Concurrent Mark Sweep)收集器(老年代)

           CMS收集器是一种以获取最短停顿时间为目标的收集器。应用于互联网,B/S系统的服务端上,因为他们重视服务的响应速度,希望系统停顿时间最短。
           CMS收集器是基于“标记一清除”算法实现的 ,它的运作过程相对于前面几种收集器来说更复杂一些,整个过程分为4个步骤,包括:
  • 初始标记( CMS initial mark ):标记GC Roots能直接关联到的对象,需要stop world
  • 并发标记( CMS concurrent mark ):进行GC Roots Tracing的过程
  • 重新标记( CMS remark ):修正并发标记时间,因为用户线程继续运行,导致标记变化,需要stop world
  • 并发清除( CMS concurrent sweep )
         由于整个过程中耗时最长的并发标记和并发清除过程收集器线程都可以与用户线程一起工作,所以 ,从总体上来说,CMS收集器的内存回收过程是与用户线程一起并发执行的。
             

          CMS还远达不到完美的程度,它有以下3个明显的缺点:1.对CPU敏感;2.CMS无法处理浮动垃圾(由于CMS并发处理阶段,用户线程还在运行,会不断地有新垃圾产生);3. 标记—清除会有大量的空间碎片。

         7.  GI(Garbage First)收集器

            G1 (Garbage-First)收集器是当今收集器技术发展的最前沿成果之一,早在JDK 1.7刚刚确立项目目标,Sun公司给出的JDK 1.7 RoadMap里面,它就被视为JDK 1.7中HotSpot虚拟机的一个重要进化特征。从JDK 6u14中开始就有Early Access版本的G1收集器供开发人员实验、试用,由此开始G1收集器的“Experimental”状态持续了数年时间,直至JDK 7u4 , Sun公 司才认为它达到足够成熟的商用程度,移除了“Experimental”的标识。

            G1是一款面向服务端应用的垃圾收集器。HotSpot开发团队赋予它的使命是(在比较长期的)未来可以替换掉JDK 1.5中发布的CMS收集器。与其他GC收集器相比,G1具备如下特点。
  • 并行与并发:G1能充分利用多CPU、多核环境下的硬件优势,使用多个CPU ( CPU或者CPU核心)来缩短Stop-The-World停顿的时间,部分其他收集器原本需要停顿Java线程执行的GC动作,G1收集器仍然可以通过并发的方式让Java程序继续执行。
  • 分代收集:与其他收集器一样,分代概念在G1中依然得以保留。虽然G1可以不需要其他收集器配合就能独立管理整个GC堆 ,但它能够采用不同的方式去处理新创建的对象和已经存活了一段时间、熬过多次GC的旧对象以获取更好的收集效果。
  • 空间整合:与CMS的“标记一清理”算法不同,G1从整体来看是基于“标记一整理”算法实现的收集器,从局部(两个Region之间)上来看是基于“复制”算法实现的,但无论如何,这两种算法都意味着G1运作期间不会产生内存空间碎片,收集后能提供规整的可用内存。这种特性有利于程序长时间运行,分配大对象时不会因为无法找到连续内存空间而提前触发下一次GC。
  • 可预测的停顿:这是G1相对于CMS的另一大优勢,降低停顿时间是G1和CMS共同的关注点 ,但G1除了追求低停顿外 ,还能建立可预测的停顿时间模型 ,能让使用 者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒 ,这几乎已经是实时Java ( RTSJ ) 的垃圾收集器的特征了。
         在G1之前的其他收集器进行收集的范围都是整个新生代或者老年代,而G1不再是这样。使用G1收集器时,Java堆的内存布局就与其他收集器有很大差别,它将整个Java堆划分为多个大小相等的独立区域(Region ) , 虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,它们都是一部分Region ( 不需要连续)的集合。
         G1收集器之所以能建立可预测的停顿时间模型,是因为它可以有计划地避免在整个Java 堆中进行全区域的垃圾收集。G1跟踪各个Region里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需时间的经验值),在后台维护一个优先列表,每次根据允许的收集时间 ,优先回收价值最大的Region ( 这就是 Garbage-First名称的来由)。这种使用Region划分内存空间以及有优先级的区域回收方式,保证了G1收集器在有限的时间内可以获取尽可能高的收集效率。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值