本文部分摘自《深入理解 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. [题解] 洛谷 P3393 逃离僵尸岛

    题目TP门 很明显是一个最短路,但是如何建图才是关键. 对于每一个不可遍历到的点,可以向外扩散,找到危险城市. 若是对于每一个这样的城市进行搜索,时间复杂度就为\(O(n^2)\),显然过不了.不妨把 ...

  2. 【Java】Java socket通信使用read,readline函数的阻塞问题

    Socket通信是Java网络编程中比较基础的部分,其原理其实就是源ip,源端口和目的ip,目的端口组成的套接字通信.其底层还设及到了TCP协议的通信. Java中的Socket通信可以通过客户端的S ...

  3. 怎么用Iometer测试存储性能

    1.Disk Targets选项栏中选择要测试的磁盘,1 per target of Outstanding I/Os 保持默认即可. 2.在Access Specifications栏中新建测试条件 ...

  4. MIT-6.006算法导论(2011秋)

    L01 Algorithmic Thinking,Peak Finding 算法定义:高效处理大量数据的程序 在学本课之前最好先学习6.042,本课进阶为6.046 本门课的8个主要章节:算法思想.排 ...

  5. fist-第九天冲刺随笔

    这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzzcxy/2018SE1 这个作业要求在哪里 https://edu.cnblogs.com/campus/fz ...

  6. DRF使用Serializer来进行序列化和反序列化操作

    在serlizers中添加 # -*- coding: utf-8 -*- from rest_framework import serializers from .models import * c ...

  7. 第5.3节 详说Python风格的函数分配参数

    一.    分配参数的定义 参数收集就是在定义函数时不能确认参数个数,用收集参数将调用时不确定数量的实参存放到收集参数的元组中.分配参数与此过程相反,它不是在定义函数形参时使用星号(1个或2个),而是 ...

  8. 第15.42节、PyQt输入部件:QFontComboBox、QLineEdit、QTextEdit、QPlainText功能详解

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.引言 输入部件量比较多,且功能很丰富,但除了用于编写编辑器.浏览器 ...

  9. 转:Python2字符编码问题汇总

    这篇文章的部分问题在Python3以后不再存在,老猿只是觉得文章的部分内容还是有参考价值,因此在此原文转发连接: Python2字符编码问题汇总

  10. PyQt(Python+Qt)学习随笔:QListWidget的addItem方法

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 在QListWidget对象中,增加一个项的方法是调用addItem方法,addItem方法有2种重 ...