本文部分摘自《深入理解 Java 虚拟机第三版》

概述

如果说收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的实践者。Java 虚拟机规范中对垃圾收集器的实现做出规定,因此不同的厂商、不同版本的虚拟机所包含的垃圾收集器各有不同。所谓经典就是在 JDK7 Update 4 以后,JDK11 发布以前的在 OpenJDK HotSpot 虚拟机所包含的全部可用的垃圾收集器。尽管这些经典垃圾收集器已算不上最先进的技术,但它们都经历了千锤百炼,基本上都是可以放心使用的垃圾收集器。各款经典垃圾收集器之间的关系如图所示,如果两个收集器之间存在连线,就说明它们可以搭配使用:

Serial 收集器

Serial 收集器是最基础、历史最悠久的收集器,在 JDK3 以前是 HotSpot 虚拟机新生代收集器的唯一选择。这个收集器是一个单线程工作的收集器。这里的单线程不仅仅是说明它只使用一条收集线程去完成垃圾收集工作,更强调的是它在进行垃圾收集时,必须暂停其他所有工作线程,直至收集结束,也即“Stop The World”。这项工作是由虚拟机在后台自动发起和完成的,用户完全不可知,也不可控,显然这令人难以接受

但 Serial 收集器也有自己的优势,那就是简单与高效(与其他收集器的单线程相比)。对于内存有限的环境,它是所有收集器里额外内存消耗最小的;对于单核处理器或处理器核心数较少的环境,Serial 收集器由于没有线程交互的开销,可以专心做垃圾收集,自然可以获得最高的单线程收集效率。在用户桌面应用场景以及近年来流行的部分微服务应用,分配给虚拟机管理的内存一般不会太大,垃圾收集的停顿时间完全可以控制在毫秒级别,这点停顿时间对于用户来说完全可以接受。所以,Serial 收集器对于运行在客户端模式下的虚拟机是一个不错的选择

ParNew 收集器

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

ParNew 收集器除了支持多线程并行收集外,其余与 Serial 收集器并无太多创新,但它却是不少运行在服务端的 HotSpot 虚拟机,尤其是 JDK7 之前的遗留系统首选的新生代收集器,其中最重要的原因是:除了 Serial 收集器,目前只有它能与 CMS 收集器配合工作。CMS 收集器是 HotSpot 虚拟机中第一款真正意义上支持并发的垃圾收集器,它首次实现了让垃圾收集器线程与用户线程(基本上)同时工作。不过由于 JDK9 以后 CMS 逐渐被 G1 所代替,ParNew 也渐渐退出了历史舞台

ParNew 收集器由于存在线程交互开销,当处于单核心处理器环境中时并不会有比 Serial 收集器更好的效果。不过,随着可以被使用的处理器核心数的增加,ParNew 对于垃圾收集时系统资源的高效利用还是很有好处的

Parallel Scavenge 收集器

Parallel Scavenge 收集器也是一款新生代收集器,它同样是基于标记 - 复制算法实现的收集器,也是能够并行收集的多线程收集器。不同于 CMS 等收集器的关注点是尽可能地缩短垃圾收集时用户线程的停顿时间,Parallel Scavenge 收集器的目标是达到一个控制的吞吐量。所谓吞吐量就是处理器用于运行用户代码的时间与处理器总消耗时间的比值,即:吞吐量 = 运行用户代码时间 / (运行用户代码时间 + 运行垃圾收集时间)

停顿时间越短,越适合需要与用户交互或需要保证服务响应质量的程序,提升用户体验;而高吞吐量则可以最高效率低利用处理器资源,尽快完成程序的运算任务。Parallel Scavenge 收集器提供了两个参数用于精确控制吞吐量,分别是控制最大垃圾收集停顿时间的 -XX:MaxGCPauseMillis 参数以及直接设置吞吐量大小的 -XX:GCTimeRatio 参数

除上述两个参数,Parallel Scavenge 收集器还有一个参数 -XX:UseAdaptiveSizePolicy,这是一个开关参数,当这个参数被激活后,就不需要人工指定新生代的大小(-Xmn)、Eden 与 Survivor 区的比例(-XX:SurvivorRatio)、晋升老年代对象大小(-XX:PretenureSizeThreshold)等细节参数了,虚拟机会根据当前系统的运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或最大1吞吐量,这种调节方式称为垃圾收集的自适应调节策略

Serial Old 收集器

Serial Old 收集器是 Serial 收集器的老年代版本,同样是一个单线程收集器,使用标记 - 整理算法。这个收集器的主要供客户端模式下的 HotSpot 虚拟机使用。如果用在服务端模式,可能有两种用途:一种是在 JDK5 及之前的版本中与 Parallel Scavenge 收集器搭配使用,另一种就是作为 CMS 收集器发生失败时的后备预案。Serial Old 收集器的工作过程如图所示:

Parallel Old 收集器

Parallel Old 是 Parallel Scavenge 收集器的老年代版本,支持多线程并发收集,基于标记 - 整理算法实现。这个收集器直到 JDK6 时才开始提供,在此之前,新生代的 Parallel Scavenge 收集器一直处于相当尴尬的状态,因为如果新生代选择了 Parallel Scavenge 收集器,那么老年代除了 Serial Old 收集器以外就别无选择,效率不高。直到 Parallel Old 收集器的出现,吞吐量优先收集器终于有了比较名副其实的搭配组合。Parallel Old 收集器的工作过程如图所示:

JVM 经典垃圾收集器的更多相关文章

  1. JVM 经典垃圾收集器 —— CMS 收集器

    本文部分摘自<深入理解 Java 虚拟机第三版> 概述 CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器.由于大部分 Java 应用主要 ...

  2. JVM经典垃圾收集器

      这个关系不是一成不变的,由于维护和兼容性测试的成本,在JDK 8时将Serial+CMS. ParNew+Serial Old这两个组合声明为废弃(JEP 173),并在JDK 9中完全取消了这些 ...

  3. JVM之垃圾收集器

    前一篇讲了垃圾收集算法--JVM之GC算法.垃圾收集算法——标记-清除算法.复制算法.标记-整理算法.分代收集算法,如果把它看作是方法论,那么下面说的就应该是内存回收的具体实现. 先看一下JVM中有哪 ...

  4. 【转载】JVM 学习——垃圾收集器与内存分配策略

    本文主要是对<深入理解java虚拟机 第二版>第三章部分做的总结,文章中大部分内容都来自这章内容,也是博客 JVM 学习的第二部分. 简述 说到垃圾收集(Garbage Collectio ...

  5. JVM、垃圾收集器

    1.Java虚拟机原理 所谓虚拟机,就是一台虚拟的机器.他是一款软件,用来执行一系列虚拟计算指令,大体上虚拟机可以分为系统虚拟机和程序虚拟机, 大名鼎鼎的Vmare就属于系统虚拟机,他完全是对物理计算 ...

  6. JVM之垃圾收集器与内存分配回收策略(二)

    上一篇JVM垃圾收集器与内存分配策略(一),下面是jdk1.7版本的垃圾收集器之间的关系,其中连线两端的两种垃圾收集器可以进行搭配使用,下面来总结一下这些收集器的一些特点以及关系. 一.Serial收 ...

  7. 理解JVM之垃圾收集器详解

    前言 垃圾收集器作为内存回收的具体表现,Java虚拟机规范并未对垃圾收集器的实现做规定,因而不同版本的虚拟机有很大区别,因而我们在这里主要讨论基于Sun HotSpot虚拟机1.6版本Update22 ...

  8. 理解JVM之垃圾收集器概述

    前言 很多人将垃圾收集(Garbage Collection)视为Java的伴生产物,实际1960年诞生的Lisp是第一门真正使用内存动态分配与垃圾手机技术的语言.在目前看来,内存的动态分配与内存回收 ...

  9. JVM各垃圾收集器对比

    本随笔是<深入理解Java虚拟机 JVM高级特性与最佳实践>读书笔记. 1.JDK1.7之后的HotSpot虚拟机所包含的所有收集器如下: 解读: 1. 总共有7种垃圾收集器 2.Seri ...

随机推荐

  1. 【HAOI2015】树上操作

    (题面来自洛谷) 题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树 ...

  2. 变更mysql的数据类型兼容小数测试

    来吧 我也没想到有一天要做这个测试: 想分为这几步吧: 1.先看看mysql本身支不支持数据的变更 2.再看看mybatis能不能用int接受double和decimal 先看下mysql: alte ...

  3. WriteFile,CreateFile,ReadFile

    原文链接:https://blog.csdn.net/Jeanphorn/article/details/44982273 将数据写入一个文件.该函数比fwrite函数要灵活的多.也可将这个函数应用于 ...

  4. Beta冲刺随笔——Day_Five

    这个作业属于哪个课程 软件工程 (福州大学至诚学院 - 计算机工程系) 这个作业要求在哪里 Beta 冲刺 这个作业的目标 团队进行Beta冲刺 作业正文 正文 其他参考文献 无 今日事今日毕 林涛: ...

  5. 【2014广州市选day1】JZOJ2020年9月12日提高B组T2 导弹拦截

    [2014广州市选day1]JZOJ2020年9月12日提高B组T2 导弹拦截 题目 Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统 V1.0.但是这种导弹拦截系统有一个缺 ...

  6. 使用SpringSecurity Oauth2.0实现自定义鉴权中心

    Oauth2.0是什么不在赘述,本文主要介绍如何使用SpringSecurity Oauth2.0实现自定义的用户校验 1.鉴权中心服务 首先,列举一下我们需要用到的依赖,本文采用的是数据库保存用户信 ...

  7. 第11.22节 Python 中re模块的字符串分割器:split函数

    一. 引言 在<第11.2节 Python 正则表达式支持函数概览>介绍了re模块的主要函数,在<第11.3节 Python正则表达式搜索支持函数search.match.fullm ...

  8. pandas 删除列

    ddf = pd.DataFrame({"id":[1,2,3], "name":[4,5,6],"age":[7,8,9]})ddf = ...

  9. 博客中css样式的正确设置

    一.简介 博客园的文章是支持html代码和css样式的,即使是markdown写作.当某个标签需要特制样式时,我们可以自定义样式来覆盖掉原本的样式. 二.css样式优先级 参考至>>菜鸟教 ...

  10. Object.prototype.toString.call()和typeof()区别

    js中判断数据类型都知道用tyoeof(),但是他只能判断object,boolean,function,string,number,undefined还有symbol(es6新增)这几种初步类型,比 ...