【JVM】经典垃圾收集器

news2024/12/27 10:46:46

文章目录

  • 说明
  • 新生代收集器
    • Serial收集器
    • ParNew收集器
    • Parallel Scavenge收集器
  • 老年代收集器
    • Serial Old收集器
    • Parallel Old收集器
    • CMS收集器
  • Garbage First收集器
    • 需要解决的问题
    • 运作过程
    • CMS和G1的区别

说明

Java中有许多垃圾收集器(Garbage Collector,GC)可供选择,每个收集器都有其独特的特性和适用场景。

image-20230909175821479

上图展示了七种作用于不同分代的收集器,如果两个收集器之间存在连线,就说明它们可以搭配使用,图中收集器所处的区域,则表示它是属于新生代收集器抑或是老年代收集器。这篇文章会介绍上面几种垃圾收集器

新生代收集器

Serial收集器

这是一个新生代的垃圾收集器,他有下面几个特点

  1. 单线程垃圾回收器:Serial收集器是单线程的,也就是说它只使用一个线程来执行垃圾回收操作。因此,它不适合多核心的处理器,不利于并行回收。
  2. 新生代收集:Serial收集器主要用于新生代的垃圾回收。在新生代中,它使用复制(Copying)算法,将存活的对象复制到一个干净的区域,然后清理不再被引用的对象。这个过程是单线程执行的。
  3. Stop-the-World暂停:Serial收集器在进行垃圾回收时需要停止应用程序的执行,这会导致一段时间的应用程序停顿,这段时间被称为"Stop-the-World"暂停。因为Serial是单线程的,所以这个停顿时间相对较长。
  4. 适用场景:由于Serial收集器是单线程的,因此它通常不适用于多核心CPU或需要低延迟的应用程序。但它在资源受限的环境下可能是一个合适的选择,例如移动设备或嵌入式系统。

还有一个Serial Old收集器用于老年代收集,下面示意了Serial/Serial Old收 集器的运行过程。

image-20230909181536247

总之,Serial垃圾回收器是Java虚拟机的一种简单的垃圾回收器,适用于一些资源受限的环境或用于简单的测试和学习。但对于需要高并发性能和低停顿时间的应用程序,通常不建议使用Serial收集器,而应考虑其他更适合多核CPU的垃圾回收器。

ParNew收集器

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

image-20230909181907214

ParNew收集器就可以简单理解为用于新生代的多线程Serial收集器

Parallel Scavenge收集器

Parallel Scavenge(并行清除)收集器是Java虚拟机的一种垃圾回收器,主要用于新生代的垃圾回收。它被设计成在多核CPU上并行执行垃圾回收操作,旨在提供高吞吐量的垃圾回收性能。

以下是关于Parallel Scavenge收集器的重要信息:

  1. 并行垃圾回收:Parallel Scavenge收集器是一种多线程垃圾回收器,它允许多个线程并行执行新生代的垃圾回收操作。这样可以充分利用多核CPU的性能,提高回收性能。
  2. 新生代收集:Parallel Scavenge主要用于新生代的垃圾回收。新生代的对象通常生命周期较短,因此使用复制算法进行垃圾回收,同时通过多线程提高回收效率。
  3. 高吞吐量:Parallel Scavenge的主要目标是提供高吞吐量,即在一段时间内尽可能多地执行应用程序的工作。它通常不追求极低的停顿时间,而是优化吞吐量。
  4. 自适应调整:Parallel Scavenge收集器具有自适应调整功能,可以根据应用程序的性能需求动态调整垃圾回收的策略。例如,可以自动调整新生代和老年代的比例,以更好地满足性能需求。
  5. Stop-the-World暂停:虽然Parallel Scavenge支持并行垃圾回收,但在进行垃圾回收时仍然需要进行短暂的"Stop-the-World"停顿,以确保一致性和安全性。
  6. 适用场景:Parallel Scavenge适用于需要高吞吐量的应用程序,通常用于后台处理任务、数据分析等需要大量计算的场景。它不太适合强调低停顿时间的应用程序。

老年代收集器

Serial Old收集器

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

Serial Old收集器的工作过程如下

image-20230909182650027

Parallel Old收集器

Parallel Old是Parallel Scavenge收集器的老年代版本,用于老年代的垃圾回收。它是Parallel Scavenge垃圾回收器的补充,旨在提供多线程的、并行执行的老年代垃圾回收,以提高垃圾回收性能。

Parallel Old收集器的工作过程如图3-10所示。Parallel Scavenge和Parallel Old一般配合使用,是一款“吞吐量优先”的收集器

image-20230909182954285

CMS收集器

CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。主要用于老年代的垃圾回收。它的主要特点是尽量减少应用程序停顿时间,特别适用于对低停顿时间要求较高的应用。

CMS的运行分为以下四个过程:

  1. 初始标记(CMS initial mark):需要”Stop The World”,仅仅只是标记一下GC Roots能直接关联到的对象,速度很快
  2. 并发标记(CMS concurrent mark):从GC Roots的直接关联对象开始遍历整个对象图的过程,这个过程耗时较长但是不需要停顿用户线程,可以与垃圾收集线程一起并发运行
  3. 重新标记(CMS remark):需要“Stop The World”,这里是为了修正并发标记期间,因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录【增量更新】
  4. 并发清除(CMS concurrent sweep):清理删除掉标记阶段判断的已经死亡的对象,由于不需要移动存活对象,所以这个阶段也是可以与用户线程同时并发的。

通过下图可以比较清楚地看到CMS收集器的运作步骤中并发和需要停顿的阶段。

image-20230909184051239

CMS也有一些缺点,如下

  • 内存碎片问题:CMS是一款基于“标记-清除”算法实现的收集器,所以会产生很多的内存碎片,这样分配大对象时就可能出现还有足够空间但是无法找 到足够大的连续空间来分配当前对象,需要提前触发一次Full GC的情况

  • 性能问题:由于在并发标记和并发清理阶段一直在运行,所以会占用一条线程。如果处理器只有4个处理器核心,那么在并发标记和并发清理阶段就会一直占用25%的处理器运算资源

  • 无法处理浮动垃圾:CMS不能处理浮动垃圾(Floating Garbage),即在并发标记阶段之后生成的垃圾。这些垃圾对象可能需要等待下一次垃圾回收才能被清除。

Garbage First收集器

G1是一种分代收集器,但它的工作方式与传统的分代收集器(新生代和老年代)有所不同。它将整个堆划分为多个区域,每个区域可以属于新生代、老年代,或是混合区。这种划分允许G1更灵活地管理内存。

G1将整个Java堆划分为多个相等大小的区域,每个区域可以是新生代区、老年代区或混合区。每个区域的大小通常在1MB到32MB之间,这些区域构成了G1的可控制的内存管理单元。Region中还有一类特殊的Humongous区域,专门用来存储大对象。G1认为只要大小超过了一个 Region容量一半的对象即可判定为大对象。

G1最主要的一个特点就是并不是一次回收所有垃圾,一次只回收一部分垃圾。G1的主要目标是按照垃圾的数量优先回收。G1会选择包含垃圾最多的区域进行回收,以尽量减小垃圾回收的停顿时间。并且我们可以指定垃圾回收的停顿时间,这时G1只会在规定时间内回收最有价值的Region(价值即回收所获得的空间大小以及回收所需时间的经验值,然后在后台维护一 个优先级列表)

下图是G1的内存布局

image-20230909192429688

image-20230909192343025

需要解决的问题

G1将堆内存“化整为零”的思路,将内存划分为多个不同大小的Region,由此也出现了许多需要解决的问题

  • 跨Region引用对象如何解决?:我们知道解决跨代引用是使用记忆集避免全堆作为GC Roots扫描的,但在G1收集器上记忆集的应用其实要复杂很多,因为它的每个Region都维护有自己的记忆集。G1的记忆集在存储结构的本质上是一 种哈希表,Key是别的Region的起始地址,Value是一个集合,里面存储的元素是卡表的索引号。这种“双向”的卡表结构(卡表是“我指向谁”,这种结构还记录了“谁指向我”)比原来的卡表实现起来更复杂,同时由于Region数量比传统收集器的分代数量明显要多得多,因此G1收集器要比其他的传统垃 圾收集器有着更高的内存占用负担。

  • 如何保证垃圾回收的准确性?:CMS收集器采用增量更新算法实现,而G1收集器则是通过原始快照(SATB)算法来实现的。垃圾收集对用户线程的影响还体现在回收过程中新创建对象的内存分配上,程序要继续运行就肯定会持续有新对象被创建,G1为每一个Region设 计了两个名为TAMS(Top at Mark Start)的指针,把Region中的一部分空间划分出来用于并发回收过 程中的新对象分配,并发回收时新分配的对象地址都必须要在这两个指针位置以上。G1收集器默认在 这个地址以上的对象是被隐式标记过的,即默认它们是存活的,不纳入回收范围。

  • 怎样建立起可靠的停顿预测模型?:G1收集器的停顿 预测模型是以衰减均值(Decaying Average)为理论基础来实现的,在垃圾收集过程中,G1收集器会记录每个Region的回收耗时、每个Region记忆集里的脏卡数量等各个可测量的步骤花费的成本,并分析得出平均值、标准偏差、置信度等统计信息。然后通过这些信息预测现在开始回收的话,由哪些Region组成回收集才可以在不超过期望停顿时间的约束下获得最高的收益。

运作过程

如果我们不去计算用户线程运行过程中的动作(如使用写屏障维护记忆集的操作),G1收集器的运作过程大致可划分为以下四个步骤:

  • 初始标记(Initial Marking):仅仅只是标记一下GC Roots能直接关联到的对象,并且修改TAMS 指针的值,让下一阶段用户线程并发运行时,能正确地在可用的Region中分配新对象。这个阶段需要停顿线程,但耗时很短,而且是借用进行Minor GC的时候同步完成的,所以G1收集器在这个阶段实际 并没有额外的停顿。 (STW)

  • 并发标记(Concurrent Marking):从GC Root开始对堆中对象进行可达性分析,递归扫描整个堆里的对象图,找出要回收的对象,这阶段耗时较长,但可与用户程序并发执行。当对象图扫描完成以后,还要重新处理SATB记录下的在并发时有引用变动的对象。

  • 最终标记(Final Marking):对用户线程做另一个短暂的暂停,用于处理并发阶段结束后仍遗留下来的最后那少量的SATB记录。 (STW)

  • 筛选回收(Live Data Counting and Evacuation):负责更新Region的统计数据,对各个Region的回收价值和成本进行排序,根据用户所期望的停顿时间来制定回收计划,可以自由选择任意多个Region构成回收集,然后把决定回收的那一部分Region的存活对象复制到空的Region中,再清理掉整个旧Region的全部空间。这里的操作涉及存活对象的移动,是必须暂停用户线程,由多条收集器线程并行完成的。(STW)

G1收集器除了并发标记外,其余阶段也是要完全暂停用户线程的。G1收集器的运作步骤中并发和需要停顿的阶段如下图

image-20230916164126393

CMS和G1的区别

  • CMS使用“标记-清除”算法。G1从整体来看是基于“标记-整理”,局部使用“标记-复制”算法。
  • CMS一次回收所有垃圾,吞吐量相对较低。G1一次回收部分垃圾,单次停顿时间可控,吞吐量更高。
  • CMS基于分代进行垃圾回收。G1基于Region进行垃圾回收。
  • CMS采用增量更新。G1使用原始快照。
  • CMS卡表简单,只有一份老年代到新生代的引用。G1卡表复杂,每个Region都要有一份,导致G1的记忆集(和其他内存消耗)可能会占整个堆容量的20%乃至更多的内存空间。
  • CMS用写后屏障来更新维护卡表。G1使用写前屏障和邂逅屏障来维护卡表。
  • 在小内存应用上CMS的表现大概率仍然要会优于G1。大内存应用上G1则大多能发挥其 优势,这个优劣势的Java堆容量平衡点通常在6GB至8GB之间。
  • G1基本已经取代CMS,CMS已经被官方标记为不推荐使用了。
    维护卡表。G1使用写前屏障和邂逅屏障来维护卡表。
  • 在小内存应用上CMS的表现大概率仍然要会优于G1。大内存应用上G1则大多能发挥其 优势,这个优劣势的Java堆容量平衡点通常在6GB至8GB之间。
  • G1基本已经取代CMS,CMS已经被官方标记为不推荐使用了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1015485.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring Cloud Alibaba系列之nacos:(5)源码本地环境搭建

传送门 Spring Cloud Alibaba系列之nacos:(1)安装 Spring Cloud Alibaba系列之nacos:(2)单机模式支持mysql Spring Cloud Alibaba系列之nacos:(3)服务注册发现 Spring Cloud Alibaba系列之nacos:(4)配置管理 为什么要搭建本地…

范文展示,如何三步写出一篇满意的论文

第一步:输入文章关键信息 文章标题,写论文的话即为拟定的论文标题,例如这篇范文中的题目为“阳明心学研究” 关键词,可以写出多个论文主题相关的关键词,用逗号分开,例如这篇范文中只写了一个关键词“王阳…

CentOS 7.6使用mysql-8.0.31-1.el7.x86_64.rpm-bundle.tar安装Mysql 8.0

https://downloads.mysql.com/archives/community/是社区版的官网,可以选择版本下载。 cat /etc/redhat-release可以看到系统版本是CentOS Linux release 7.6.1810 (Core),uname -r可以看到版本是3.10.0-957.el7.x86_64。 yum remove -y mysql-libs把…

计算机硬件基本组成和各硬件工作原理

计算机硬件基本组成和各硬件工作原理 计算机硬件基本组成早期冯若依曼机的结构冯若依曼机的特点 现代计算机的结构思维导图 各硬件工作原理主存储器运算器控制器I/O 计算机硬件基本组成 计算机硬件基本组成可分两大类 1.早期冯若依曼机的结构 2.现代计算机的结构 早期冯若依曼机…

类与对象的创建

package com.mypackage.oop.later;//学生类 //类里面只存在属性和方法 public class Student {//属性:字段//在类里面方法外面定义一个属性(或者说是变量),然后在方法里面对他进行不同的实例化String name; //会有一个默认值&…

在word文档中找不到endnote的选项卡

本人由于在下载endnote之后才下载的office,所以导致在word文档中找不到endnote的选项卡,自己摸索到了解决方法。 首先确保已经拥有word与endnote之后,右键endnote打开所在文件夹: 在文件夹中找到这个Configure endnote.exe运行 之…

three.js简单3D图形的使用

npm init vitelatest //创建一个vite的脚手架 选择 Vanilla 之后自己处理一下 在main.js中写入 // 导入three.js import * as THREE from three// 创建场景 const scene new THREE.Scene();// 创建相机 const camera new THREE.PerspectiveCamera(45, //视角window.inner…

【Unity程序技巧】Unity中的单例模式的运用

👨‍💻个人主页:元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏:Uni…

el-checkbox-group限制勾选数量

<!--* Description: 视频监控 页面* Author: mhf* Date: 2023-08-15 13:26:33 --> <template><div class"videoSurveillance"><el-row :gutter"24"><el-col :span"4"><div class"videoSurveillance-left&…

亚马逊评分规则是什么,如何提高亚马逊等级评分-站斧浏览器

亚马逊平台的账户评级问题&#xff0c;如果账号评级比较差的话&#xff0c;那么会有一些不好的影响&#xff0c;因此卖家朋友们需要想办法去提升自己的账户评级。那么亚马逊评分规则是什么&#xff0c;如何提高亚马逊等级评分。 亚马逊评分规则是什么&#xff1f; 所有新卖家…

看阿里测试工程师如何玩转postman+newman+jenkins接口自动化

postman用来做接口测试非常方便&#xff0c;接口较多时&#xff0c;则可以实现接口自动化 一、环境准备 1.安装nodejs6.0 安装nodejs6.0&#xff08;github上面写的版本要求&#xff09;&#xff0c;用于安装newman4.0&#xff0c;到nodejs官网下载即可https://nodejs.org/en/…

集成Activiti-Modeler流程设计器

集成Activiti-Modeler流程设计器 Activiti Modeler 是 Activiti 官方提供的一款在线流程设计的前端插件&#xff0c;可以方便流程设计与开发人员绘制流程图&#xff0c;保存流程模型&#xff0c;部署至流程定义等等。 1、材料准备 首先我们需要获取activiti-explorer.zip&…

(三十)大数据实战——HBase集成部署安装Phoenix

前言 Phoenix 是一个开源的分布式关系型数据库查询引擎&#xff0c;它基于 Apache HBase构建。它提供了在 Hadoop 生态系统中使用 SQL查询和事务处理的能力。本节内容我们主要介绍一下Hbase如何集成部署安装Phoenix服务工具&#xff0c;并集成hive框架&#xff0c;能够快速、灵…

什么是16S rRNA,rDNA, 菌群研究为什么用16S测序,细菌如何命名分类?

谷禾健康 当谈到肠道菌群研究时&#xff0c;16S测序是一种常用的方法&#xff0c;它在了解微生物组成和多样性方面非常重要且实用。 16S rRNA是细菌和古细菌中的一个高度保守的基因片段&#xff0c;同时具有一定的变异性。通过对16S rRNA基因进行测序&#xff0c;可以确定微生物…

9.3.5网络原理(应用层HTTP/HTTPS)

一.HTTP: 1. HTTP是超文本传输协议,除了传输字符串,还可以传输图片,字体,视频,音频. 2. 3.HTTP协议报文格式:a.首行,b.请求头(header),c.空行(相当于一个分隔符,分隔了header和body),d.正文(body). 4. 5.URL:唯一资源描述符(长度不限制). a. b.注意:查询字符串(query stri…

Linux内核源码分析 (B.x)Linux内核的页面分配机制

一、伙伴系统 如果不遵循以上原则&#xff0c;在一个很大的连续空间里&#xff0c;会出现不连续的空洞&#xff0c;造成外部碎片 一般MAX_ORDER取11&#xff0c;也就是说Linux内核最大分配的最大内存块为2^10个页面&#xff0c;大小为4MB。 二、迁移类型 使用迁移类型可以实现…

【多区域电力系统模型】三区域电力系统的LQR和模糊逻辑控制(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

去耦电路设计应用指南(一)MCU去耦设计介绍

&#xff08;一&#xff09;MCU去耦设计介绍 1. 概述2. MCU需要去耦的原因2.1 去耦电路简介2.2 电源噪声产生的原因2.3 插入损耗2.4 去耦电路简介 参考资料来自网上&#xff1a; 1. 概述 我们经常看到单片机或者IC电路管脚常常会放置一个或者多个陶瓷电容&#xff0c;他们主要…

典型数据结构-栈/队列/链表、哈希查找、二叉树(BT)、线索二叉树、二叉排序树(BST树)、平衡二叉树(AVL树)、红黑树(RB树)

目录 典型数据结构列举 栈/队列/链表 树 二叉树 线索二叉树 二叉排序树 平衡二叉树&#xff08;AVL树&#xff09; 红黑树 其它树种和应用介绍 典型数据结构列举 栈/队列/链表 描述略。 一些基本的简单实现参考/数据结构简单实现/文件夹里面。 线性表详解&#xff…

Python用正则化Lasso、岭回归预测房价、随机森林交叉验证鸢尾花数据可视化2案例|数据分享...

全文链接&#xff1a;https://tecdat.cn/?p33632 机器学习模型的表现不佳通常是由于过度拟合或欠拟合引起的&#xff0c;我们将重点关注客户经常遇到的过拟合情况&#xff08;点击文末“阅读原文”获取完整代码数据&#xff09;。 相关视频 过度拟合是指学习的假设在训练数据上…