当前位置: 首页 > news >正文

【JVM】7种经典的垃圾收集器

文章目录

  • 1. 垃圾收集器概述
  • 2. Serial 收集器
  • 3. ParNew 收集器
  • 4. Paraller Scavenge 收集器
  • 5. Serial Old收集器
  • 6. Parller Old收集器
  • 7. CMS 收集器
  • 8. Garbage First 收集器

本文参考:深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)

1. 垃圾收集器概述

image-20230212113322170

图中所示七种垃圾收集器虽然算不上先进技术,但是它们在实践中足够成熟,基本上可以认为是现在未来两、三年内,能够在生产环境上放心使用的所有垃圾收集器了。

这七种垃圾收集器是作用于不同分代的,两个收集器之间若有连线,则说明它们可以搭配使用。垃圾收集器的位置则表示了属于新生代还是老年代收集器。

垃圾收集器根据发展实践可以分为:

  1. 串行
  2. 吞吐量优先
  3. 响应时间优先

2. Serial 收集器

Serial收集器是最基础、历史最悠久的收集器。它是用于新生代的垃圾收集器。

这个收集器是一个单线程工作的收集器,“单线程”不仅仅代表了这个收集器只会使用一个处理器或一个收集线程去进行垃圾收集工作,更重要的是,Serial 收集器在进行垃圾收集的时候必须暂停其他所有工作,直到收集工作完成。

也就是说在用户不可知、不可控的情况下,把用户的正常工作的线程全部停掉,这是一个不能接受的事情。

image-20230212114757514

即使 Serial 收集器是最早出现的垃圾收集器,但是如今HotSpot虚拟机运行在客户端模式下的默认新生代收集器依然是 Serial 收集器。

Serial 收集器的优点很简单,那就是简单高效,在内存资源受限的环境中,它是所有收集器里额外内存消耗最小的,对于单核处理器或核心数较小的处理器来说,Serial 收集器没有线程交互的开销,专心做垃圾收集因此保证了收集效率。


3. ParNew 收集器

ParNew 收集器实际上就是 Serail 收集器的多线程版本,除了同时使用多线程进行垃圾回收之外,其他的任何行为包括所有控制参数、收集算法等都与 Serail 收集器一样,并无太多创新之处

image-20230212115554893

并且除了Serial收集器外,目前只有ParNew收集器可以与CMS收集器配合工作。

CMS是一款在强交互应用中几乎可称为具有时代意义的垃圾收集器,它是真正意义上支持并发的垃圾收集器,首次实现了让垃圾收集器线程在用户线程同时工作,所以,CMS的出现巩固了ParNew的地位

ParNew 收集器在单核心处理器的环境绝对不必Serial收集器更好的效果,甚至存在线程交互的开销。
ParNew收集器通过超线程技术实现的伪双核处理器环境中都不能百分之百超越Serial。

不过随着处理器核心数量的增加,ParNew对于垃圾收集时的系统资源高效利用还是很有好处的,它默认开启的收集线程数和处理器核心线程数相同。


4. Paraller Scavenge 收集器

Paraller Scavenge 收集器是基于标记-复制算法实现的收集器,也是能够并行收集的多线程收集器。

该垃圾收集器常被称为“吞吐量优先收集器”

并行:并行描述的是多条垃圾收集器线程之间的关系,说明同一时间有多条这样的线程在协同工作,通常默认此时用户线程是处于等待状态

并发:并发描述的是垃圾收集器线程与用户线程之间的关系,说明同一时间垃圾收集器线程与用户线程都在运行。由于用户线程并未被冻结,所以程序仍然能响应服务请求,但由于垃圾收集器线程占用了一部分系统资源,此时应用程序的处理的吞吐量将受到一定影响。

Paraller Scavenge 收集器的特点是达到一个可控的吞吐量。

image-20230212133427488

Parallel Scavenge 收集器提供了两个参数用于精确控制吞吐量,分别是控制最大垃圾收集停顿时间的-XX:MaxGCPauseMillis 参数以及直接设置吞吐量大小的-XX:GCTimeRatio 参数

  1. -XX:MaxGCPauseMillis:参数允许值是一个大于0的毫秒数,收集器会尽力保证内存回收花费时间不超过用户的设定值,**但是这个参数值不建议设置得更小一点,因为垃圾收集停顿时间是牺牲吞吐量和新生代空间为代价的。**系统把新生代调的小一点,垃圾收集速度肯定快一点,但是随之而来的就是频繁的垃圾收集,因此吞吐量也会下来。
  2. -XX:GCTimeRatio:值应该是一个大于0小于100的正数,也就是垃圾收集时间总时间的比率,相当于吞吐量的倒数。比如设置为19,那么就是允许的最大垃圾收集器占用的时间为5%(即1/(1+19));默认为99,允许的最大1%(1/(1+99))为垃圾收集时间

5. Serial Old收集器

Serial Old收集器是Serial收集器的老年代版本,同样也是一个单线程收集器,使用标记-整理算法

image-20230212135752822

如果在服务端模式下,它也可能有两种用途:一种是在JDK 5以及之前的版本中与 Parallel Scavenge 收集器搭配使用9,另外一种就是作为 CMS 收集器发生失败时的后备预案,在并发收集发生Concurrent Mode Failure 时使用。


6. Parller Old收集器

Parller Old收集器是Parller Scavenge收集器的老年代版本,支持多线程并发收集,基于标记-整理算法实现。

image-20230212140005545

在Parller Old收集器没有出现之前,Parller Scavenge收集器只能和Serial Old收集器搭配使用,由于Serial Old收集器应用性能上的拖累,并不能是的Parller Scavenge收集器未必能发挥出最好的吞吐量最大化的效果。这组合甚至不如ParNew加CMS的组合来得优秀。

直到 Paraller old 收集器出现后,“吞吐量优先”收集器终于有了比较名副其实的搭配组合,在注重吞吐量或者处理器资源较为稀缺的场合,都可以优先考虑 Paraller Scavenge 加Paraller Old 收集器这个组合。


7. CMS 收集器

CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。目前很大一部分的 Java 应用集中在互联网网站或者基于浏览器的 B/S 系统的服务端上,这类应用通常都会较为关注服务的响应速度希望系统停顿时间尽可能短,以给用户带来良好的交互体验。

CMS收集器是基于标记-清除算法实现的。它的回收垃圾的步骤如下

  1. 初始标记

    1. 需要Stop The Word,仅仅标记从GC Roots的直接关联对象,速度很快
  2. 并发标记

    1. 从GC Roots的直接关联对象开始遍历整个对象图的过程,过程耗时但不需要停顿用户线程,可以与垃圾收集线程一起并发允许
  3. 重新标记

    1. 需要Stop The Word,为的是修正并发标记期间,因用户程序继续允许而导致标记产生变动的拿一些对象的标记记录。
    2. 停顿时间比初始标记时间常,但比并发标记时间短
  4. 并发清除

    1. 清除标记阶段判断已经死亡的对象,由于不需要移动存活对象,所以这个阶段也是可以和用户进程同时运行的

image-20230212140536014

CMS的优点的优点有并发收集、低停顿。

不过CMS并没有达到完美,它有以下几个缺点

  1. CMS收集器对处理器资源非常敏感
  2. CMS无法处理浮动垃圾
    1. 由于并发标记和并发清除阶段,用户线程是继续运行的,程序在运行的时候自然会产生新的垃圾对象。
  3. 由于使用标记-清除算法实现,所以会导致空间碎片比较多。

8. Garbage First 收集器

Garbage First 收集器也成为G1收集器,它是垃圾收集器技术发展历史上的里程碑式的成果,它开创了收集器面向局部收集的设计思路和基于 Region 的内存布局形式。

G1收集器面向堆内存任何部分来组成回收集 (Collection Set,一般简称 CSet)进行回收,衡量标准不再是它属于哪个分代,而是哪块内存中存放的垃圾数量最多,回收收益最大,这就是 G1 收集器的 Mixed GC 模式。

G1开创的基于 Region 的堆内存布局是它能够实现这个目标的关键。虽然 G1 也仍是遵循分代收集理论设计的,但其堆内存的布局与其他收集器有非常明显的差异:G1 不再坚持固定大小以及固定数量的分代区域划分,而是把连续的 Java 堆划分为多个大小相等的独立区域(Region),每一个Region 都可以根据需要,扮演新生代的 Eden 空间、Survivor 空间或者老年代空间。收集器能够对扮演不同角色的 Region 采用不同的策略去处理,这样无论是新创建的对象还是已经存活了一段时间、熬过多次收集的旧对象都能获取很好的收集效果。

Region 是 G1收集器的单位回收的最小单位,这样做可以有计划避免整个JAVA堆中进行全区域的垃圾收集。并且G1收集器会跟踪各个Region的价值大小,也就是回收所获得的空间大小以及回收所需要的时间的经验值,在后台形成一个优先队列,再根据用户设定的允许的停顿时间,优先处理那些回收价值大的Region,这样保证了G1收集器在有限的时间内获取尽可能高的收集效率。

image-20230212161608985

G1收集器的运作步骤

  1. 初始标记
    1. 仅仅只是标记一下GC Roots 能直接关联到的对象并且修改 TAMS 指针的值,让下一阶段用户线程并发运行时,能正确地在可用的 Region 中分配新对象。这个阶段需要停顿线程,但耗时很短,而且是借用进行Minor GC 的时候同步完成的,所以G1 收集器在这个阶段实际并没有额外的停顿。
  2. 并发标记
    1. 从GC Root开始对堆中对象进行可达性分析,递归扫描整个堆里的对象图,找出要回收的对象,这阶段耗时较长,但可与用户程序并发执行。当对象图扫描完成以后,还要重新处理 SATB 记录下的在并发时有引用变动的对象。
  3. 最终标记
    1. 对用户线程做另一个短暂的暂停,用于处理并发阶段结束后仍遗留下来的最后那少量的 SATB 记录。
  4. 筛选回收
    1. 负责更新 Region 的统计数据,对各个Region 的回收价值和成本进行排序,根据用户所期望的停顿时间来制定回收计划,可以自由选择任意多个 Region 构成回收集,然后把决定回收的那一部分Region 的存活对象复制到空的 Region 中,再清理掉整个旧 Region 的全部空间。这里的操作涉及存活对象的移动,是必须暂停用户线程,由多条收集器线程并行完成的。

image-20230212162540809


相关文章:

【JVM】7种经典的垃圾收集器

文章目录1. 垃圾收集器概述2. Serial 收集器3. ParNew 收集器4. Paraller Scavenge 收集器5. Serial Old收集器6. Parller Old收集器7. CMS 收集器8. Garbage First 收集器本文参考:深入理解Java虚拟机:JVM高级特性与最佳实践(第3版&#xff…...

2023/2/12总结

滑动窗口(1)滑动窗口是一种基于双指针的思想,两个指针指向的元素形成一个窗口。一般用于求取数组或字符串的某个子串、子序列、最长最短等最值或者求某个目标值时,并且该问题本身可以通过暴力解决。滑动窗口分为固定窗口和不定窗口…...

Linux之正则表达式

正则表达式是组成“操作”的基本语法,而这些“操作”是应用于Sed和Awk必备的能力。因此只有了解了正则表达式,才能学好Sed和Awk。正则表达式分为基础正则表达式(Regular Expression)与扩展正则表达式(Extended Regular…...

前端高频面试题-HTML和CSS篇(一)

💻 前端高频面试题-HTML和CSS篇(一) 🏠专栏:前端面试题 👀个人主页:繁星学编程🍁 🧑个人简介:一个不断提高自我的平凡人🚀 🔊分享方向…...

Redis 专题总结

1. 什么是Redis ? 处理:内容缓存,主要用于处理大量数据的高访问负载。Redis是一款高性能的NOSQL系列的非关系型数据库,NoSQL(NoSQL Not Only SQL),意即“不仅仅是SQL”,是一项全新的数据库理念&#xff0…...

【Python百日进阶-Web开发-Vue3】Day515 - Vue+ts后台项目2:登录页面

文章目录 一、创建登录路由1.1 安装 Vue VSCode Snippets插件1.2 处理路径引用的红色波浪线1.3 入口文件 main.ts1.4 主组件 App.vue1.5 路由文件 router/index.ts1.6 首页组件 views/HomeView.vue1.7 登录组件 views/LoginView.vue二、实现登录页面的表单展示2.1 element-plus…...

【博客620】prometheus如何优化远程读写的性能

prometheus如何优化远程读写的性能 场景 为了解决prometheus本地存储带来的单点问题,我们一般在高可用监控架构中会使用远程存储,并通过配置prometheus的remote_write和remote_read来对接 远程写优化:remote_write 远程写的原理&#xff1a…...

redis可视工具AnotherRedisDesktopManager的使用

redis可视工具AnotherRedisDesktopManager的使用 简介 Another Redis DeskTop Manager 是一个开源项目,提供了以可视化的方式管理 Redis 的功能,可供免费下载安装,也可以在此基础上进行二次开发,主要特点有: 支持 W…...

【idea】idea生产类注释和方法注释

网上有很多类似的文章,但是我在按照他们的文章设置后,出现了一些问题,因此我这边在解决了问题后,总结一篇文章,发出来给大家借鉴一下。在此先说明一下idea的版本,是2020.1.3 设置动态模板,File…...

jenkins +docker+python接口自动化之jenkins容器安装python3(二)

jenkins dockerpython接口自动化之jenkins容器安装python3(二) 目录:导读 前提是在docker下已经配置好jenkins容器了,是将python安装在jenkins容器下的 1、先看你的jenkins是否安装好 2、以root权限进入jenkins容器&#xff1…...

go 命令行工具整理

这里会整理可能会使用到的命令行参数,比如 go build、go run,诸如此类。了解这些内容对我们工作会有什么帮助吗?更多的时候,是能让我们理解代码编译的意图,或者,给我们一种排查问题的手段。 比方说&#x…...

RuntimeError: CUDA out of memory

今天在训练模型的时候突然报了显存不够的问题,然后分析了一下,找到了解决的办法,这里记录一下,方便以后查阅。 注:以下的解决方案是在模型测试而不是模型训练时出现这个报错的! RuntimeError: CUDA out of…...

Kubernetes1.25中Redis集群部署实例

1、概述我们知道在 Kubernetes 容器编排平台中, 我们可以非常方便的进行应用的扩容缩, 同时也能非常方便的进行业务的迭代,本章主要讲解在Kubernetes1.25搭建Redis单实例和Redis集群主从同步的环境流程步骤, 如果是高频访问重要的线上业务我们最好是部署在物理机器上…...

C++11实现计算机网络中的TCP/IP连接(Windows端)

目录引言1、TCP2、IP2.1 IP路由器3、TCP/IP4、TCP/IP协议C11实现参考文献引言 TCP/IP 指传输控制协议/网际协议(Transmission Control Protocol / Internet Protocol)。[1] 在TCP/IP协议簇中主要包含以下内容: TCP (传输控制协议) - 应用程序…...

Spring框架自定义实现IOC基础功能/IDEA如何手动实现IOC功能

继续整理记录这段时间来的收获,详细代码可在我的Gitee仓库Java设计模式克隆下载学习使用! 7.4 自定义Spring IOC 创建新模块,结构如图![[Pasted image 20230210173222.png]] 7.4.1 定义bean相关POJO类 7.4.1.1 定义propertyValue类 /** …...

pip离线安装windows版torch

文章目录前言conda创建虚拟环境安装torchtorch官网在线安装离线手动安装测试是否安装成功后记前言 学习的时候遇到几个机器学习相关的项目,由于不同的项目之间用到的依赖库不太一样,于是想利用conda为不同的项目创建不同的环境方便管理和运行&#xff0…...

Redis核心知识点

Redis核心知识点Redis核心知识点大全五种数据类型redis整合SpringBoot序列化问题渐进式扫描慢查询缓存相关问题数据库和缓存谁先更新缓存穿透缓存雪崩缓存击穿实际应用超卖问题分布式锁全局唯一ID充当消息队列Feed流附近商户签到HyperLogLog实现UV统计持久化RDBAOF持久化小结事…...

14. 最长公共前缀

14. 最长公共前缀 一、题目描述: 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀,返回空字符串 “”。 示例 1: 输入:strs [“flower”,“flow”,“flight”] 输出:“fl” 示例 2: …...

SignalR注册成Windows后台服务,并实现web前端断线重连

注意下文里面的 SignalR 不是 Core 版本,而是 Framework 下的 本文使用的方式是把 SignalR 写在控制台项目里,再用 Topshelf 注册成 Windows 服务 这样做有两点好处 传统 Window 服务项目调试时需要“附加到进程”,开发体验比较差&#xf…...

【前端笔试题二】从一个指定数组中,每次随机取一个数,且不能与上次取数相同,即避免相邻取数重复

前言 本篇文章记录下我在笔试过程中遇到的真实题目,供大家参考。 1、题目 系统给定一个数组,需要我们编写一个函数,该函数每次调用,随机从该数组中获取一个数,且不能与上一次的取数相同。 2、思路解析 数组已经有了…...

专栏关注学习

Node学习专栏(全网最细的教程) 【spring系列】 SpringCloud 前端框架Vue java学习过程 RocketMQ Spring Tomcat websocket 从头开始学Redisson 从头开始学Oracle 跟着大宇学Shiro 吃透Shiro源代码 Git基础与进阶 Java并发编程 Spring系列 手写…...

【手写 Vuex 源码】第八篇 - Vuex 的 State 状态安装

一,前言 上一篇,主要介绍了 Vuex 模块安装的实现,针对 action、mutation、getter 的收集与处理,主要涉及以下几个点: Vuex 模块安装的逻辑;Vuex 代码优化;Vuex 模块安装的实现;Vue…...

Mac下拉式终端的安装与配置 (iTerm2)

Mac下拉式终端的安装与配置 使用效果如图所示 安装前置软件 iTerm2 很可惜,如此炫酷的功能在原终端中并不能实现,我们需要借助iTerm2这个软件来实现。 官网链接:iTerm2 - macOS Terminal Replacement 我们点击download下载即可 配置 当我…...

使用 Spring 框架结合阿里云 OSS 实现文件上传的代码示例

使用 Spring 框架结合阿里云 OSS 实现文件上传的代码示例POM文件配置文件上传工具类控制层使用yaml配置文件(第二种用法,看公司要求)注入 OSSClient 对象及工具类(第二种用法,看公司要求)使用 Vue 前端代码…...

神经网络基础知识

神经网络基础知识 文章目录神经网络基础知识一、人工神经网络1.激活函数sigmod函数Tanh函数Leaky Relu函数分析2.过拟合和欠拟合二、学习与感知机1.损失函数与代价函数2. 线性回归和逻辑回归3. 监督学习与无监督学习三、优化1.梯度下降法2.随机梯度下降法(SGD)3. 批量梯度下降法…...

SpringBoot开发规范部分通用模板+idea配置【项目通用-1】

SpringBoot开发规范通用模板 1 分页插件使用 通过MybatisPlus配置分页插件拦截器 Configuration MapperScan("com.xuecheng.content.mapper") //拦截的mapper层 public class MybatisPlusConfig {//定义分页的拦截器Beanpublic MybatisPlusInterceptor getMybatisPl…...

程序的机器级表示part3——算术和逻辑操作

目录 1.加载有效地址 2. 整数运算指令 2.1 INC 和 DEC 2.2 NEG 2.3 ADD、SUB 和 IMUL 3. 布尔指令 3.1 AND 3.2 OR 3.3 XOR 3.4 NOT 4. 移位操作 4.1 算术左移和逻辑左移 4.2 算术右移和逻辑右移 5. 特殊的算术操作 1.加载有效地址 指令效果描述leaq S, DD…...

基于YOLOV5的钢材缺陷检测

数据和源码见文末 1.任务概述 数据集使用的是东北大学收集的一个钢材缺陷检测数据集,需要检测出钢材表面的6种划痕。同时,数据集格式是VOC格式,需要进行转化,上传的源码中的数据集是经过转换格式的版本。 2.数据与标签配置方法 在数据集目录下,train文件夹下有训练集数据…...

Session与Cookie的区别(三)

中场休息 让我们先从比喻回到网络世界里,HTTP 是无状态的,所以每一个 Request 都是不相关的,就像是对小明来说每一位客人都是新的客人一样,他根本不知道谁是谁。 既然你没办法把他们关联,就代表状态这件事情也不存在。…...

七大设计原则之接口隔离原则应用

目录1 接口隔离原则介绍2 接口隔离原则应用1 接口隔离原则介绍 接口隔离原则(Interface Segregation Principle, ISP)是指用多个专门的接口,而不使用单一的总接口,客户端不应该依赖它不需要的接口。这个原则指导我们在设计接口时…...

有域名有空间如何做网站/网站建设优化

近期客服遇到一个问题,说看不到千牛聊天记录了,本来聊过的客户,打开对话框聊天记录显示的是空白的,点击历史聊天记录也是空白的。问我应该怎么解决,我梳理了一下解决的方法,希望能对大家有帮助。如图&#…...

ui网页界面设计素材/seo教程

一个日期时间显示框的美化风格示例,在网页上显示时间的一个美化示例,为时间显示框增加了一个漂亮的外框,这个外框是基于图片来美化的,,虽然现在都不主张用图片来美化了,不过看上去还真是挺漂亮的。www.srcf…...

网站开发属于技术合同/百度官网电话

一、Java反射机制概述 Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个Class对象),这…...

网站关键字优化地点/百度广告推广电话

从选择Java GPL许可方式开源,到扩展X86产品线,到现在的股票代码由“SUNW”改变为“JAVA”,施瓦兹正在向我们展现一个全新的、灵活的而不是食古不化的Sun。IT 需要的是创新、创新、再创新,任何固执己见的家伙注定要被淘汰。在大家都…...

哪些网站是单页面应用程序/免费搭建网站平台

假设现在有一个二分类问题,先引入两个概念: 真正例率(TPR):正例中预测为正例的比例假正例率(FPR):反例中预测为正例的比例 再假设样本数为6,现在有一个分类器1&#xff…...

工程信息网站谁做/百度新闻客户端

Introduction 参考链接:2014斯坦福大学机器学习视频 本篇是针对当凭直觉做完一个Baseline以后,如何提高现有的识别率?依然凭直觉有以下几种方法: 1、增加训练数据集 2、挑选出更少的特征 3、增加其他特征 4、增加多项式x1*x2 5、减少…...