本篇内容包括:7 种 Jvm 垃圾回收器的介绍、对比 以及 对应的 Jvm 参数设置,这 7 种包括了:Serial、ParNew 以及 Parallel Scavenge 三种新生代回收器 和 :Serial Old、Parallel Old 以及 CMS 三种老年代回收器,此外还有一个 G1 回收器是 Java 目前比较前沿的成果…

一、Jvm 垃圾回收器概述

我们前面提到了,垃圾回收器的 回收的内容、回收的时机以及回收的方式,接下来我们来看 Java 垃圾回收器。如果垃圾回收算法是内存回收的方法论的话,那么垃圾回收器就是内存回收的具体实现了。

Jvm 的垃圾回收器根据场景和实现方式可以分为新生代回收器和老年代回收器,新生代回收器与老年代回收器可以搭配使用。

  • 新生代回收器包括:Serial、ParNew 以及 Parallel Scavenge;
  • 老年代回收器包括:Serial Old、Parallel Old 以及 CMS;
  • 此外,Java7 update 4(第七版第四个更新升级包)之后引入了一个 G1 收集器。

Ps:不同垃圾回收器适合于不同的内存区域,有的两个垃圾回收器之间也可以配合使用!


二、新生代回收器

1、Serial 收集器

Serial 收集器是最基础且历史最悠久的垃圾收集器,作为单线程工作的收集器。Serial 会在它工作时要求暂停用户所有的其他线程(Stop-the-World 机制)。采用的是 “标记-复制” 算法。垃圾清理时,Serial 回收器不存在线程间的切换,因此,在单 CPU 的环境下,垃圾清除效率比较高。

虽然 Serial 收集器是最基础最老的收集器,但是迄今为止 HotSpot 虚拟机运行在 Client 模式下的默认的新生代垃圾收集器!相较于其他收集器,Serial 具有以下 3 个优点:

  1. 简单高效;
  2. 所有收集器中额外内存消耗最少;
  3. 针对内存几十兆或一两百兆的新生代,停顿时间能控制在一百毫秒内。

Ps:这里需要注意的一点是 Serial 收集器和 Serial Old 收集器在垃圾收集时不是单线程的,通常所描述的"单线程"是指的垃圾回收时暂停其他所有的工作线程。

2、ParNew 收集器

ParNew 收集器大致可以理解为是 Serial 收集器的多线程版本,因为 ParNew 收集器除了采用并行回收的方式执行内存回收外,与 Serial 收集器之间几乎没有任何区别。ParNew 收集器在年轻代中同样也是采用复制算法、Stop-the-World 机制。

ParNew 收集器是很多版本 Jvm(包括 HotSpot)运行在 Server 模式下新生代的默认垃圾收集器。

ParNew 收集器运行在多 CPU 的环境下,由于可以充分利用多 CPU、多核心等物理硬件资源优势,可以更快的完成垃圾收集,提升程序的吞吐量。但是在单个 CPU 的环境下,ParNew 收集器不比 Serial 收集器更高效,虽然 Serial 收集器是基于串行回收,但是由于 CPU不需要频繁的切换,因此可以有效避免多线程交互过程中产生的一些额外开销。

Ps:除了 Serial 外,目前只有 ParNew GC 能与 CMS 收集器配合工作。

3、Parallel Scavenge 收集器

Parallel Scavenge 收集器同 ParNew 收集器一样,也是采用 “标记-复制” 算法,且为能够并行收集的多线程收集器。

Parallel Scavenge 的特点是其关注重点为吞吐量,高吞吐量则可以高效率地利用 CPU 时间,尽快完成程序的运算,但也就是说它的线程单次停止时间可能更长,因此适用于后台计算型任务程序:

Ps:如果虚拟机完成某个任务,用户代码加上垃圾收集总共耗费了 100 分钟,其中垃圾收集花掉 1 分 钟,那吞吐量就是 99% :
吞吐量=运行用户代码时间/运行用户代码时间+运行垃圾回收时间吞吐量=运行用户代码时间/运行用户代码时间+运行垃圾回收时间 吞吐量=运行用户代码时间/运行用户代码时间+运行垃圾回收时间


三、老年代回收器

1、Serial Old 收集器

Serial Old 是 Serial 收集器的老年代版本,采用“标记-整理”算法,单线程收集器,也是给 Client 模式下的虚拟机使用。

Ps:在 Jdk1.5 及其以前,它常与 Parallel Scavenge 回收器配合使用,达到较好的吞吐量,另外它也是 CMS 回收器在 Concurrent Mode Failure 时的后备方案。

2、Parallel Old 收集器

Parallel Old 回收器是 Parallel Scavenge 回收器的老生代版本,属于多线程回收器,采用“标记-整理”算法。Parallel Old 回收器和 Parallel Scavenge 回收器同样考虑了吞吐量优先这一指标,非常适合那些注重吞吐量和 CPU 资源敏感的场合。

Ps:在注重吞吐量以及 CPU 资源敏感的场合,可以优先考虑 Parallel Scavenge 加 Parallel Old 收集器

3、CMS 收集器

CMS 收集器,是一种以获取最短回收停顿时间为目标的收集器,其缩写含义为 Concurrent Mark Sweep,Mark Sweep 指的是“标记-清除”算法,在互联网网站、B/S 架构的中常用的收集器就是 CMS,因为系统停顿的时间最短,给用户带来较好的体验。

CMS收集器的运作过程分为4个步骤,包括:

  • 初始标记(短暂),仅仅只是标记一下 GCRoots 能直接关联到的对象,速度很快;
  • 并发标记(和用户的应用程序同时进行),进行 GCRoots 追踪的过程,标记从 GCRoots 开始关联的所有对象开始遍历整个可达分析路径的对象。这个时间比较长,所以采用并发处理(垃圾回收器线程和用户线程同时工作);
  • 重新标记(短暂),为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间一般会比初始标记阶段稍长一些,但远比并发标记的时间短;
  • 并发清除(和用户的应用程序同时进行):垃圾回收

整个过程中耗时最长的并发标记和并发清除过程收集器线程都可以与用户线程一起工作,所以,从总体上来说,CMS 收集器的内存回收过程是与用户线程一起并发执行的。


四、G1 收集器

G1(Garbage-First)收集器是最前沿的成果之一,在Java7 update 4之后引入(Jdk7 的第 4 个版本),是一款面向服务端应用的垃圾收集器。在多 CPU 和大内存的场景下有很好的性能。HotSpot 开发团队赋予它的使命是未来可以替换掉 CMS 收集器。

G1 是一个分代的,增量的,并行与并发的“标记-复制”垃圾回收器。它的设计目标是为了适应现在不断扩大的内存和不断增加的处理器数量,进一步降低暂停时间(pause time),同时兼顾良好的吞吐量。

G1收集器的优势:

  • 独特的分代垃圾回收器,分代GC: 分代收集器,同时兼顾年轻代和老年代;

  • 使用分区算法,不要求 eden,年轻代或老年代的空间都连续;

  • 并行性: 回收期间,可由多个线程同时工作,有效利用多核cpu资源;

  • 空间整理: 回收过程中,会进行适当对象移动,减少空间碎片;

  • 可预见性: G1 可选取部分区域进行回收,可以缩小回收范围,减少全局停顿。

G1收集器的阶段分以下几个步骤:

  1. 初始标记(它标记了从GC Root开始直接可达的对象);

  2. 并发标记(从GC Roots开始对堆中对象进行可达性分析,找出存活对象);

  3. 最终标记(标记那些在并发标记阶段发生变化的对象,将被回收);

  4. 筛选回收(首先对各个Regin的回收价值和成本进行排序,根据用户所期待的GC停顿时间指定回收计划,回收一部分Region)。


五、相关知识点

1、HotSpot 的 Server 和 Client 两种模式

HotSpot 包括 Server 和 Client 两种模式的实现:

  • Java HotSpot Client VM(-client),为在客户端环境中减少启动时间而优化;
  • Java HotSpot Server VM(-server),为在服务器环境中最大化程序执行速度而设计。

比较:Server VM 启动比 Client VM 慢,运行比 Client VM 快。Server 模式的运行中,垃圾回收处理做的比较好一些。

2、设置回收器的参数

下面给出配置回收器时,经常使用的参数:

  • -XX:+UseSerialGC:在新生代和老年代使用串行收集器
  • -XX:+UseParNewGC:在新生代使用并行收集器
  • -XX:+UseParallelGC :新生代使用并行回收收集器,更加关注吞吐量
  • -XX:+UseParallelOldGC:老年代使用并行回收收集器
  • -XX:ParallelGCThreads:设置用于垃圾回收的线程数
  • -XX:+UseConcMarkSweepGC:新生代使用并行收集器,老年代使用CMS+串行收集器
  • -XX:ParallelCMSThreads:设定CMS的线程数量
  • -XX:+UseG1GC:启用G1垃圾回收器

3、各类回收器总结

回收器 回收代 回收模式 回收算法 特点
Serial 新生代 单线程 标记-复制 简单高效,内存消耗少, 停顿时间能控制在一百毫秒内
ParNew 新生代 多线程 标记-复制 Serial 的多线程版本
Parallel Scavenge 新生代 多线程 标记-复制 关注重点为吞吐量
Serial Old 老年代 单线程 标记-整理 同 Serial 简单高效,内存消耗少
Parallel Old 老年代 多线程 标记-整理 同 Parallel Scavenge 适合那些注重吞吐量和 CPU 资源敏感的场合
CMS 老年代 多线程 标记-清除 并发收集、低停顿,但是会产生大量空间碎片、并发阶段会降低吞吐量
G1 多线程 标记-复制 同时兼顾年轻代和老年代,针对于大 heap

垃圾回收器的选用决定因素:应用程序的场景、硬件的制约 以及 吞吐量的需求。

  • 串行垃圾回收是最简单的也是效率最低的,如果只是控制台的单线程程序,简单任务,并且机器配置不高,推荐使用。
  • 并行垃圾回收器是 64bit server 默认的垃圾回收器,一般我们工作和生产上默认不配置,都是并行垃圾回收。对于一般的不要求吞吐的应用,并且硬件资源不是太充足的情况下,并行垃圾回收器差不多能满足需求。
  • CMS 垃圾回收器是对并行垃圾回收器的一个优化,它以 CPU 和系统资源为代价,换取 GC 的延迟。不会一 GC 就 STW,而是根据情况 STW。一定程度上是资源换取速度。
  • G1 垃圾回收器是针对于大 heap 的垃圾回收器,如果 heap 分配的足够大,分的 region 的优先级回收策略会优先清理垃圾多的 region 并且减少了内存空间碎片,分配大对象时不会因为无法找到连续内存空间而提前触发下一次 GC。

深入理解Java虚拟机:Java垃圾回收器相关推荐

  1. java虚拟机之垃圾回收器

    2019独角兽企业重金招聘Python工程师标准>>> 1. 引言 垃圾回收器主要需要完成 3 件事: 哪些内存需要回收 什么时候回收 如何回收 在上一篇博客已经介绍了 java 内 ...

  2. Java虚拟机的垃圾回收器以及内存分配策略详解

    概述 垃圾回收器(GC)是什么以及为什么我们需要垃圾回收器?? 垃圾回收是Java语言区别于其他语言的一种最为重要的特性之一, 通过垃圾回收器(Garbage Collection)来实现对我们Jav ...

  3. Java虚拟机-经典垃圾回收器

    如果说收集算法是内存回收的方法论,那垃圾收集器就是内存回收的实践者.接下来我们将介绍已经在Jvm里面使用过,或者未来可能会使用的垃圾回收器. 1 Serial 收集器 Serial收集器是最基础,历史 ...

  4. 浅析Java虚拟机的垃圾回收机制(GC)

    目录 一.垃圾回收机制(Garbage Collection) 二.对象回收的时机 引用计数法 可达性分析算法 三.垃圾回收算法 标记-清除算法 标记-复制算法 标记-整理算法 新生代.老年代.永久代 ...

  5. 学习笔记【Java 虚拟机②】垃圾回收

    若文章内容或图片失效,请留言反馈.部分素材来自网络,若不小心影响到您的利益,请联系博主删除. 总目录 学习笔记[Java 虚拟机①]内存结构 学习笔记[Java 虚拟机②]垃圾回收 学习笔记[Java ...

  6. java虚拟机多久触发垃圾回收_每日一问:讲讲 Java 虚拟机的垃圾回收

    昨天我们用比较精简的文字讲了 Java 虚拟机结构,没看过的可以直接从这里查看: 每日一问:你了解 Java 虚拟机结构么? 今天我们必须来看看 Java 虚拟机的垃圾回收算法是怎样的.不过在开始之前 ...

  7. Java虚拟机之垃圾回收详解一

    Java虚拟机之垃圾回收详解一 Java技术和JVM(Java虚拟机) 一.Java技术概述: Java是一门编程语言,是一种计算平台,是SUN公司于1995年首次发布.它是Java程序的技术基础,这 ...

  8. 深入理解Java虚拟机-Java内存区域透彻分析

    Java虚拟机深入理解系列全部文章更新中- 深入理解Java虚拟机-Java内存区域透彻分析 深入理解Java虚拟机-常用vm参数分析 深入理解Java虚拟机-JVM内存分配与回收策略原理,从此告别J ...

  9. 深入理解Java虚拟机—Java虚拟机内存

    之前的内容: 上一篇:深入理解Java虚拟机-Java历史以及Java虚拟机历史 下一篇:深入理解Java虚拟机-垃圾收集算法 一.运行时数据区分为五个区域 1. 程序计数器 他可以看作是当前线程所执 ...

  10. 深入理解JVM虚拟机之垃圾回收

    深入理解JVM虚拟机之垃圾回收 什么叫做垃圾? 没有引用指向得对象都称为垃圾,好比如我们放风筝,哪些断了线得风筝都称之为垃圾. JVM怎么查找这些垃圾 一般又两种算法,1.可达性分析.2.引用计数 引 ...

最新文章

  1. Spring之注解方式实例化Java类
  2. 剑指offer(牛客)——从尾到头打印链表
  3. 几个主流的Java连接池整理
  4. 子图同构算法——Ullmann算法(1)不包含refine procedure的简单穷举算法。
  5. springboot quartz 动态配置_springboot集成quartz实现动态任务调度
  6. Spring Tool Suite 4 添加反编译插件
  7. tomcat7.0支持什么版本的jdk_恭喜你喜提JDK,那你知道JDK是什么吗?先来看看吧
  8. 正则表达式与html信息提取,基于正则表达式的HTML信息提取.pdf
  9. Charles抓包工具安装与配置
  10. jquery请求后台数据(get请求)
  11. python3.6安装cv2库_win10 +python3.6环境下安装opencv以及pycharm导入cv2有问题的解决办法...
  12. 如何写好简历及如何准备面试(转)
  13. movebase导航
  14. java实现上传文件
  15. OLED屏幕的手机和LCD屏幕的手机,到底哪个好?
  16. 蛋白质结构预测---残基接触的基础知识(二)
  17. 函数与映射的区别和联系
  18. 分享一个stm8s003单片机的ADC转换,附加一个冒泡算法(用于减少误差)
  19. 计算机网络构成的硬件和软件有哪些,计算机的硬件构成及软件构成 有什么
  20. 兄dei,帮我开一下门吧~

热门文章

  1. php取名字的姓,姓名拆分为姓氏和名字的方法[php版]
  2. 【计量统计】计量经济学导论常见公式原理及习题解答
  3. 【笔记】高斯金字塔和拉普拉斯金字塔:高斯金字塔持续的下采样让图片变小,像素变少,特征模糊;拉普拉斯金字塔以记录恢复原图过程中的上采样后图片与原始图片的损失,力图还原真实图片
  4. STM32+ MAX30102通过指尖测量心率+血氧饱和度
  5. linux防火墙关了端口还是不通,为什么linux防火墙关了 端口不通
  6. mvn命令无效之为idea自带maven配置环境变量
  7. 【Cadence生成网表失败排查思路】
  8. 使用Jquery完成动态表格的功能
  9. imx6ull系统移植--uboot
  10. 如何测试代理IP的质量?