6. 垃圾收集器

1 前言

如果说收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现。Java虚拟机规范中对垃圾收集器应该如何实现并没有任何规定,因此不同的厂商、版本的虚拟机所提供的垃圾收集器都可能会有很大差别,并且一般都会提供参数供用户根据自己的应用特点和要求组合出各个年代所使用的收集器。

1.1 新生代、老年代垃圾收集器组合

在这里插入图片描述

2 Serial 收集器

2.1 概念

Serial 收集器是最基本的收集器,曾经(JDK1.3.1之前)是新生代唯一的收集器。这个收集器是一个单线程的收集器,但是“单线程”的意义并不是他只会使用一个CPU或一条线程去完成垃圾收集工作。更重要的是他在垃圾收集的时候,必需暂停其他所有的工作线程,直到它收集结束(STOP THE WORLD)。

2.2 运行示意图

在这里插入图片描述

2.3 应用场景

使用复制算法,位于新生代。应用场景于Client模式或单CPU环境。

2.4 优缺点

  • 优点:单CPU环境下收集效率最高。
  • 缺点:目前环境基本为多核CPU环境,效率低。存在STW。

3 ParNew 收集器

3.1 概念

ParNew 收集器收集器其实就是 Serial 收集器的多线程版本,除了使用多线程进行垃圾收集之外,其余行为包括 Serial 收集器可用的所有控制参数、收集算法、Stop The world、对象分配规则、回收策略等都与Serial收集器完全一样,实现上这两种收集器也共用了相当多的代码。

3.2 运行示意图在这里插入图片描述

3.3 应用场景

使用复制算法,位于新生代。应用场景于Server模式。

3.4 优缺点

  • 优点:并发执行GC。
  • 缺点:单CPU效率不如Serial。存在STW。

4 Parallel Scavenge 收集器

4.1 概念

Parallel Scavenge 收集器是一个新生代收集器,采用复制算法,并且是多线程收集器。Parallel Scavenge 收集器的关注点与其他收集器不同,CMS等收集器的关注点是尽可能缩短垃圾收集时用户线程的停顿时间,而Parallel Scavenge 收集器的目标则是达到一个可控制的吞吐量(Throughput)。这里所谓的吞吐量是指CPU用于运行用户代码的时间与CPU总消耗时间的比值,既吞吐量 = 运行用户代码时间 / (运行用户代码时间 + 垃圾收集时间),虚拟机总共运行了100分钟,其中垃圾收集花掉了1分钟,那么吞吐量就是99%。

停顿时间越短就越适合需要与用户交互的程序,良好的响应速度能提升用户体验,而高吞吐量则可以高效的利用CPU时间,尽快完成程序的运算任务,主要适合在后台运算而不需要太多交互的任务。

4.2 运行示意图

在这里插入图片描述

4.3 应用场景

使用复制算法,位于新生代。应用场景于高吞吐量为目标,即减少垃圾收集时间,让用户代码获得更长的运行时间。当应用程序运行在具有多个CPU上,对暂停时间没有特别高的要求。

4.4 优缺点

  • 优点:并发执行GC;高吞吐量为目标,即减少垃圾收集时间。
  • 缺点:存在STW。

5 Serial Old 收集器

5.1 概念

Serial Old 收集器是 Serial 收集器的老年代版本,它同样是一个单线程收集器,使用“标记-整理”算法。这个收集器的主要也是在目前的JAVA的Client模式下的虚拟机使用。如果在Server模式下,它主要还有两大用途:一个是在JDK 1.5及之前的版本中与Parallel Scavenge收集器搭配使用,另外一个就是作为CMS收集器的后备预案。如果CMS收集器出现Concurrent Mode Failure,则Serial Old收集器将作为后备收集器。

5.2 运行示意图

在这里插入图片描述

5.3 应用场景

使用标记-整理算法,位于老年代。应用场景于 Client 模式或单 CPU 环境。Server 模式下在 JDK1.5 及之前,与 Parallel Scavenge 收集器搭配使用(JDK1.6 有 Parallel Old 收集器可搭配)。

5.4 优缺点

  • 优点:单CPU环境下收集效率最高;简单高效。
  • 缺点:目前环境基本为多核CPU环境,效率低。存在STW。

6 Parallel Old 收集器

6.1 概念

Parallel Old 收集器是 Parallel Scavenge 收集器的老年代版本,用于老年代的垃圾回收,但与 Parallel Scavenge 不同的是,它使用的是“标记-整理算法”。适用于注重于吞吐量及CPU资源敏感的场合。

6.2 运行示意图

在这里插入图片描述

6.3 应用场景

使用标记-整理算法,位于老年代。应用场景于 JDK1.6 及之后用来代替老年代的 Serial Old 收集器,特别是 Server 模式、多 CPU 情况以及在注重吞吐量以及CPU资源敏感的场景。

6.4 优缺点

  • 优点:注重吞吐量。
  • 缺点: CPU资源敏感。存在STW。

7 CMS 收集器

7.1 概念

CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。目前很大一部分的Java应用集中在互联网站或者B/S系统的服务端上,这类应用尤其重视服务的响应速度,希望系统停顿时间最短,以给用户带来较好的体验。CMS收集器就非常符合这类应用的需求。

从名字中包含“Mark Sweep”就可以看出,CMS收集器是基于“标记一清除”算法实现的。

整个过程分为4个步骤,包括:

  1. 初始标记(CMS initial mark)
  2. 并发标记(CMS concurrent mark)
  3. 重新标记(CMS remark)
  4. 并发清除(CMS concurrent sweep)

7.2 运行示意图

在这里插入图片描述

7.3 应用场景

使用标记-清除算法,位于老年代。应用于以获取最短回收停顿时间为目标,与用户交互较多的场景。如常见WEB、B/S系统的服务器上的应用。

7.4 优缺点

  • 优点:以获取最短回收停顿时间为目标。并发收集、低停顿。以给用户带来较好的体验。
  • 缺点:产生大量内存碎片。需要更多的内存。对CPU资源非常敏感。无法处理浮动垃圾。

8 G1 收集器

8.1 概念

G1(Garbage-First)是一款面向服务端应用的垃圾收集器,JDK 7 Update4后开始进入商用。HotSpot开发团队赋予它的使命是未来可以替换掉JDK 1.5中发布的CMS收集器。之前提供的收集器都是仅作用于新生代或者是老年代,但是G1收集器可以作用于新生代和老年代,因为使用G1收集器是java heap的内存结构有很大的不同,它将整个Java堆划分为多个大小相等的独立区域(Region),虽然还保留有新生代和老年代的概念,但是他们已经没有了物理上的隔阂了,它们都是region的一部分的集合。

如果不计算维护Remembered Set的操作,G1收集器的运作大致可划分为以下几个步骤:

  1. 初始标记(Initial Marking)
  2. 并发标记(Concurrent Marking)
  3. 最终标记(Final Marking)
  4. 筛选回收(Live Data Counting and Evacuation)

8.2 运行示意图

在这里插入图片描述

8.3 应用场景

使用多种算法,同时位于新生代与老年代。应用场景主要是面向服务端应用,针对具有大内存、多处理器的机器;最主要的应用是为需要低GC延迟,并具有大堆的应用程序提供解决方案。

8.4 优缺点

  • 优点:最主要的应用是为需要低GC延迟,并具有大堆的应用程序提供解决方案;最主要的应用是为需要低GC延迟,并具有大堆的应用程序提供解决方案;最主要的应用是为需要低GC延迟,并具有大堆的应用程序提供解决方案。
  • 缺点:内存要求高,使用记忆集占大量内存,维护记忆集带来更高的执行负载。

9 垃圾收集器对比

序号名称算法分代是否单线程用户线程与GC线程是否支持并发
1Serial复制新生代
2Serial Old标记-整理老年代
3ParNew复制新生代
4Parallel Scavenge复制新生代
5Parallel Old标记-整理老年代
6CMS标记-清除老年代
7G1多种回收算法新生代、老年代
序号名称使用场景优缺点参数
1SerialClient模式或单CPU环境优:单CPU环境下收集效率最高;简单高效。缺:目前环境基本为多核CPU环境,效率低。存在STW“-XX:+UseSerialGC”:添加该参数来显式的使用串行垃圾收集器;
2Serial OldClient模式或单CPU环境。Server模式下在JDK1.5及之前,与Parallel Scavenge收集器搭配使用(JDK1.6有Parallel Old收集器可搭配)优:单CPU环境下收集效率最高;简单高效。缺:目前环境基本为多核CPU环境,效率低“-XX:+UseSerialGC”:添加该参数来显式的使用串行垃圾收集器;
3ParNewServer模式优:并发执行GC。缺:单CPU效率不如Serial。存在STW“-XX:+UseConcMarkSweepGC”:指定使用CMS后,会默认使用ParNew作为新生代收集器;"-XX:+UseParNewGC":强制指定使用ParNew;"-XX:ParallelGCThreads":指定垃圾收集的线程数量,ParNew默认开启的收集线程与CPU的数量相同;
4Parallel Scavenge高吞吐量为目标,即减少垃圾收集时间,让用户代码获得更长的运行时间。当应用程序运行在具有多个CPU上,对暂停时间没有特别高的要求优:并发执行GC;高吞吐量为目标,即减少垃圾收集时间。缺:存在STW“-XX:MaxGCPauseMillis"控制最大垃圾收集停顿时间;”-XX:GCTimeRatio" 设置垃圾收集时间占总时间的比率;"-XX:+UseAdptiveSizePolicy"
5Parallel OldJDK1.6及之后用来代替老年代的Serial Old收集器,特别是Server模式、多CPU情况下。在注重吞吐量以及CPU资源敏感的场景。优:注重吞吐量。缺: CPU资源敏感;存在STW“-XX:+UseParallelOldGC”:指定使用Parallel Old收集器
6CMS以获取最短回收停顿时间为目标;与用户交互较多的场景;如常见WEB、B/S系统的服务器上的应用优:以获取最短回收停顿时间为目标;并发收集、低停顿;以给用户带来较好的体验。缺:产生大量内存碎片;需要更多的内存;对CPU资源非常敏感;无法处理浮动垃圾。“-XX:+UseConcMarkSweepGC”:指定使用CMS收集器
7G1面向服务端应用,针对具有大内存、多处理器的机器;最主要的应用是为需要低GC延迟,并具有大堆的应用程序提供解决方案优:最主要的应用是为需要低GC延迟,并具有大堆的应用程序提供解决方案;最主要的应用是为需要低GC延迟,并具有大堆的应用程序提供解决方案;最主要的应用是为需要低GC延迟,并具有大堆的应用程序提供解决方案。缺:内存要求高,使用记忆集占大量内存,维护记忆集带来更高的执行负载“-XX:+UseG1GC”:指定使用G1收集器;"-XX:InitiatingHeapOccupancyPercent":当整个Java堆的占用率达到参数值时,开始并发标记阶段;默认为45;"-XX:MaxGCPauseMillis":为G1设置暂停时间目标,默认值为200毫秒;"-XX:G1HeapRegionSize":设置每个Region大小,范围1MB到32MB;目标是在最小Java堆时可以拥有约2048个Region

10 引用

  • 《深入理解Java虚拟机 JVM高级特性与最佳实践》-周志明著
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值