垃圾收集器

HotSpot虚拟机包含的所有收集器如图3-5所示。图3-5展示了7种作用于不同分代的收集器,如果两个收集器之间存在连线,就说明它们可以搭配使用。

新生代收集器:Serial、ParNew、Parallel Scavenge,新生代收集器均采用复制算法

老年代收集器:Serial Old(标记-整理算法)、Parallel Old(标记-整理算法)、CMS(标记-清除算法)

不分代的收集器:G1(整体来看基于标记-整理和局部来看基于复制算法)

图3-5 HotSpot虚拟机的垃圾收集器

一、Serial收集器

Serial收集器是一个单线程的收集器,它的“单线程”的意义并不仅仅说明它只会使用一个CPU或一条收集线程去完成垃圾收集工作,更重要的是在它进行垃圾收集时,必须暂停其他所有的工作线程,直到它收集结束。这个过程常被称为“Stop The World”。

实际上到现在为止,它依然是虚拟机运行在Client模式下的默认新生代收集器。它也有着优于其他收集器的地方:简单而高效(与其他收集器的单线程比),对于限定单个CPU的环境来说,Serial收集器由于没有线程交互的开销,专心做垃圾收集自然可以获得最高的单线程收集效率。

图3-6 Serial/Serial Old收集器运行示意图

二、 ParNew收集器

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

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

图3-7 ParNew/Serial Old收集器运行示意图

三、Parallel Scavenge收集器

Parallel Scavenge收集器是一个新生代收集器,它也是使用复制算法的收集器,又是并行的多线程收集器……看上去和ParNew都一样,那它有什么特别之处呢?Parallel Scavenge收集器的特点是它的关注点与其他收集器不同,CMS等收集器的关注点是尽可能地缩短垃圾收集时用户线程的停顿时间,而Parallel Scavenge收集器的目标则是达到一个可控制的吞吐量(Throughput)。所谓吞吐量就是CPU用于运行用户代码的时间与CPU总消耗时间的比值,即吞吐量 = 运行用户代码时间 /(运行用户代码时间 +垃圾收集时间),虚拟机总共运行了100分钟,其中垃圾收集花掉1分钟,那吞吐量就是99%。

四 、Serial Old收集器

Serial Old是Serial收集器的老年代版本,它同样是一个单线程收集器,使用“标记-整理”算法。这个收集器的主要意义也是在于给Client模式下的虚拟机使用。如果在Server模式下,那么它主要还有两大用途:一种用途是在JDK 1.5以及之前的版本中与Parallel Scavenge收集器搭配使,另一种用途就是作为CMS收集器的后备预案,在并发收集发生Concurrent Mode Failure时使用。这两点都将在后面的内容中详细讲解。Serial Old收集器的工作过程如图3-8所示。

图3-8 Serial/Serial Old收集器运行示意图

五、Parallel Old收集器

Parallel Old是Parallel Scavenge收集器的老年代版本,使用多线程和“标记-整理”算法。直到Parallel Old收集器出现后,“吞吐量优先”收集器终于有了比较名副其实的应用组合,在注重吞吐量以及CPU资源敏感的场合,都可以优先考虑Parallel Scavenge加Parallel Old收集器。Parallel Old收集器的工作过程如图3-9所示。

图3-9 Parallel Scavenge/Parallel Old收集器运行示意图

六、CMS收集器

CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。它在垃圾收集时使得用户线程和GC线程并发执行,因此在GC过程中用户也不会感受到明显卡顿.但用户线程和GC线程之间不停地切换会有额外的开销,因此垃圾回收总时间就会被延长。CMS收集器是基于“标记—清除”算法实现的。

1、运行过程

它的运作过程相对于前面几种收集器来说更复杂一些,整个过程分为4个步骤,包括:

(1)初始标记(CMS initial mark)

(2)并发标记(CMS concurrent mark)

(3)重新标记(CMS remark)

(4)并发清除(CMS concurrent sweep)

其中,初始标记、重新标记这两个步骤仍然需要“Stop The World”。初始标记仅仅只是标记一下GC Roots能直接关联到的对象,速度很快,并发标记阶段就是进行GC Roots Tracing的过程,而重新标记阶段则是为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间一般会比初始标记阶段稍长一些,但远比并发标记的时间短。

由于整个过程中耗时最长的并发标记和并发清除过程收集器线程都可以与用户线程一起工作,所以,从总体上来说,CMS收集器的内存回收过程是与用户线程一起并发执行的。通过图3-10可以比较清楚地看到CMS收集器的运作步骤中并发和需要停顿的时间。

图3-10 Concurrent Mark Sweep收集器运行示意图

2、CMS的缺点

CMS有以下3个明显的缺点:

(1)CMS收集器对CPU资源非常敏感。

当CPU不足4个(譬如2个)时,CMS对用户程序的影响就可能变得很大,如果本来CPU负载就比较大,还分出一半的运算能力去执行收集器线程,就可能导致用户程序的执行速度忽然降低了50%,其实也让人无法接受。

(2)CMS收集器无法处理浮动垃圾

由于垃圾清除过程中,用户线程和GC线程并发执行,也就是用户线程仍在执行,那么在执行过程中会产生垃圾,这些垃圾称为"浮动垃圾".

(3)会产生大量碎片空间

CMS是一款基于“标记—清除”算法实现的收集器,收集结束时会有大量空间碎片产生。

(4)吞吐量低

由于CMS在垃圾收集过程使用用户线程和GC线程并行执行,从而线程切换会有额外开销,因此CPU吞吐量就不如在GC过程中停止一切用户线程的方式来的高。

七、G1收集器

1、G1收集器概述

G1(Garbage-First)收集器,追求停顿时间、多线程GC、面向服务端应用。整体来看基于标记-整理和局部来看基于复制算法合并。

它将整个Java堆划分为多个大小相等的独立区域(Region),虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,它们都是一部分Region(不需要连续)的集合。

G1跟踪各个Region里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需时间的经验值),在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的Region(这也就是Garbage-First名称的来由)。

2、G1的特点。

(1)并行与并发

G1能充分利用多CPU、多核环境下的硬件优势,使用多个CPU(CPU或者CPU核心)来缩短Stop-The-World停顿的时间,部分其他收集器原本需要停顿Java线程执行的GC动作,G1收集器仍然可以通过并发的方式让Java程序继续执行。

(2)分代收集

与其他收集器一样,分代概念在G1中依然得以保留。虽然G1可以不需要其他收集器配合就能独立管理整个GC堆,但它能够采用不同的方式去处理新创建的对象和已经存活了一段时间、熬过多次GC的旧对象以获取更好的收集效果。

(3)空间整合

与CMS的“标记—清理”算法不同,G1从整体来看是基于“标记—整理”算法实现的收集器,从局部(两个Region之间)上来看是基于“复制”算法实现的,但无论如何,这两种算法都意味着G1运作期间不会产生内存空间碎片,收集后能提供规整的可用内存。这种特性有利于程序长时间运行,分配大对象时不会因为无法找到连续内存空间而提前触发下一次GC。

(4)可预测的停顿

这是G1相对于CMS的另一大优势,降低停顿时间是G1和CMS共同的关注点,但G1除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒,这几乎已经是实时Java(RTSJ)的垃圾收集器的特征了。

3、G1收集器的运行过程

G1收集器的运作大致可划分为以下几个步骤:

(1)初始标记(Initial Marking)

(2)并发标记(Concurrent Marking)

(3)最终标记(Final Marking)

(4)筛选回收(Live Data Counting and Evacuation)

《深入理解Java虚拟机》读书笔记:垃圾收集器的更多相关文章

  1. 深入理解Java虚拟机 -- 读书笔记(1):JVM运行时数据区域

    深入理解Java虚拟机 -- 读书笔记:JVM运行时数据区域 本文转载:http://blog.csdn.net/jubincn/article/details/8607790 本系列为<深入理 ...

  2. 《深入理解 Java 虚拟机》学习 -- 垃圾收集器

    <深入理解 Java 虚拟机>学习 -- 垃圾收集器 1. Serial 收集器(新生代) 含义: 单线程收集器. 缺点: 进行垃圾收集时,必须暂停其他所有的工作线程. 优点: 简单而高效 ...

  3. 【Todo】深入理解Java虚拟机 读书笔记

    有一个在线系列地址 <深入理解Java虚拟机:JVM高级特性与最佳实践(第2版)> http://book.2cto.com/201306/25426.html 已经下载了这本书(60多M ...

  4. 深入理解Java虚拟机读书笔记2----垃圾收集器与内存分配策略

    二 垃圾收集器与内存分配策略 1 JVM中哪些内存需要回收?     JVM垃圾回收主要关注的是Java堆和方法区这两个区域:而程序计数器.虚拟机栈.本地方法栈这3个区域随线程而生,随线程而灭,随着方 ...

  5. 深入理解Java虚拟机读书笔记5----虚拟机字节码执行引擎

    五 虚拟机字节码执行引擎   1 运行时栈帧结构     ---栈帧是用于支持虚拟机进行方法调用和方法执行的数据结构,是虚拟机运行时数据区中的虚拟机栈的栈元素.     ---栈帧中存储了方法的局部变 ...

  6. 深入理解Java虚拟机读书笔记1----Java内存区域与HotSpot虚拟机对象

    一 Java内存区域与HotSpot虚拟机对象 1 Java技术体系.JDK.JRE?     Java技术体系包括:         · Java程序设计语言:         · 各种硬件平台上的 ...

  7. 深入理解java虚拟机读书笔记--java内存区域和管理

    第二章:Java内存区域和内存溢出异常 2.2运行时数据区域 运行时数据区分为方法区,堆,虚拟机栈,本地方法栈,程序计数器 方法区和堆是线程共享的区域 虚拟机栈,本地方法栈,程序计数器是数据隔离的数据 ...

  8. 深入理解Java虚拟机——读书笔记

    首先 强烈推荐周志明老师的这本书,真的可以说是(起码中文出版界)新手了解Java虚拟机必须人手一本的教科书!!!   第二部分自动内存管理机制 由于Java虚拟机的多线程是通过线程轮流切换并分配处理器 ...

  9. 深入理解Java虚拟机(四)——HotSpot垃圾收集器详解

    垃圾收集器 新生代收集器 1.Serial收集器 特点: 单线程工作,收集的时候就会停止其他所有工作线程,用户不可知不可控,会使得用户界面出现停顿. 简单高效,是所有收集器中额外内存消耗最少的. 没有 ...

  10. 深入理解Java虚拟机读书笔记 -- Java内存区域

    Graal VM: Run Programs Faster Anywhere. 跨语言全栈虚拟机,可以作为"任何语言"的运行平台使用. Java内存结构 程序计数器:线程私有,较小 ...

随机推荐

  1. vue全家桶进阶之路28:项目仓库Gitee

    Gitee(之前称为GitCafe)是一种基于web的Git仓库托管服务,在中国很受欢迎.它为开发人员提供了一个平台,可以托管他们的Git仓库,与其他开发人员协作,并管理他们的代码. https:// ...

  2. 一些JS过滤方法

    一般过滤器我们都会卸载过滤filter文件内 本文这里就直接写正常methods格式的 //过滤空格 filterSpaces(data) { return data.replace(/\s+/g, ...

  3. IntelliJ IDEA上手这一篇就够了,从入门到上瘾

    前言 每次换电脑,最最最头疼的事情莫过于安装各种软件和搭建开发环境.这算是不想换电脑的一个原因吧(最主要还是穷).除非是电脑坏了开不了机或者点一下卡一下,真不想换电脑.每次换电脑都得折腾好久. 趁着这 ...

  4. 2019年蓝桥杯C/C++大学B组省赛真题(数的分解)

    题目描述: 把2019分解成3个各不相同的正整数之和,并且要求每个正整数都不包含数字2和4,一共有多少种不同的分解方法? 注意交换3个整数的顺序被视为同一种方法,例如1000+1001+18 和100 ...

  5. Curl 中 关于PUT, POST, DELETE, UPDATE 的使用

    POST curl -H "Content-Type:application/json" -X POST --data '{"id":1, "text ...

  6. 揭秘 Task.Wait

    目录 简介 背后的实现 Task.Wait 的两个阶段 SpinWait 阶段 BlockingWait 阶段 Task.Wait 可能会导致的问题 可能会导致线程池饥饿 可能会导致死锁 .NET 6 ...

  7. .NET7 for LoongArch64(国产龙芯)

    目前龙芯通过自己的指令集LA64支持了.Net7.0.1版本,一同被支持的有Ruby,Nodejs,Java,Electron,Python等.原文:在此处 龙芯.Net7 sdk下载地址: http ...

  8. PRF评价

    PRF评价指标: 精确率P:预测结果正类数量占全部结果的比率: P= $\frac{TP}{TP+FP}$ TP:预测为真且实际为真,FP为预测真实际为假. 召回率R:在所有正类样本中,能回想到的比例 ...

  9. spring-boot-plus2.7.12版本重磅发布,三年磨一剑,兄弟们等久了,感谢你们的陪伴

    Everyone can develop projects independently, quickly and efficiently! spring-boot-plus是一套集成spring bo ...

  10. 2020中国系统架构师大会活动回顾:ZEGO实时音视频服务架构实践

    10月24日,即构科技后台架构负责人&高级技术专家祝永坚(jack),受邀参加2020中国系统架构师大会,在音视频架构与算法专场进行了主题为<ZEGO实时音视频服务架构实践>的技术 ...