JVM——垃圾回收器

2023-11-09

JVM——垃圾回收器

  • 按照工作模式分,可以分为并发式垃圾回收器独占式垃圾回收器
  • 并发式垃圾回收器与应用程序线程交替工作,以尽可能减少应用程序的停顿时间
  • 独占式垃圾回收器(stop the world)一旦运行,就停止应用程序中的所有用
    户线程,直到垃圾回收过程完全结束
    在这里插入图片描述
  • 按碎片处理方式分,可分为压缩式垃圾回收器非压缩式垃圾回收器
    压缩式垃圾回收器会在回收完成后,对存活对象进行压缩整理
    消除回收后的碎片非压缩式的垃圾回收器不进行这步操作。
  • 按工作的内存区间分,又可分为年轻代垃圾回收器老年代垃圾回收器

垃圾回收器(7大经典)

串行回收器: serial、serial old
并行回收器: ParNew、Parallel scavenge、Parallel old
并发回收器:CMS、G1

收集器与垃圾分代的关系

在这里插入图片描述
在这里插入图片描述

serial -》 serial old
parNaw -》CMS GC -》(备用)serial old
parallel GC -》parallel
old GC G1 -》 G1
根据场景使用最使用的收集器。

Serial回收器(串行回收)

在这里插入图片描述

总结:
这种垃圾收集器大家了解,现在已经不用串行的了。而且在限定单核cpu才可以用。现在都不是单核的了。
对于交互较强的应用而言,这种垃圾收集器是不能接受的。一般在Javaweb应用程序中是不会采用串行垃圾收集器的。

ParNew回收器(并行回收)

Par是Parallel的缩写,New:只能处理的是新生代
在这里插入图片描述
对于新生代,垃圾回收次数较频繁,我们可以使用并行,来使垃圾回收和应用线程交替执行,减少STW暂停时间。
对于老年代,垃圾回收次数较少,我们使用串行的方式,来减少线程切换消耗的资源。

Parallel回收器(吞吐量优先)

和ParNew收集器不同,Parallel scavenge收集器的目标则是达到一个可控制的吞吐量(Throughput),它也被称为吞吐量优先的垃圾收集器。
自适应调节策略也是Parallel scavenge与ParNew一个重要区别。
在这里插入图片描述
如图所示新生代采用的也是复制算法,同样用的是并行的方式,来减少STW暂停时间
老年代采用的是标记-压缩算法,与parNew不同的是采用的是并行的方式

总结:

在程序吞吐量优先的应用场景中,Parallel收集器和Parallel old收集器的组合,在server模式下的内存回收性能很不错。 在Java8中,默认是此垃圾收集器。

CMS回收器(低延迟)

CMS收集器的关注点是尽可能缩短垃圾收集时用户线程的停顿时间
CMS的垃圾收集算法采用标记-清除算法,并且也会"stop-the-world"

在这里插入图片描述

  • 第一阶段初始标记(串行): 此阶段会标记GC Roots直接关联的对象,但是在此操作的期间会触发STW,但这个过程也是极快的
  • 第二阶段并发标记(并行): 此阶段会从GC Roots直接关联的对象开始遍历整个对象树,对其标记,这个过程是并行进行的,用户线程和垃圾回收是同时进行,不会出现暂停。
  • 第三阶段重新标记(并行): 因为之前的并发标记是并行进行的,用户可能在标记的过程中又使对象要进行回收了,此阶段就是为了重新标记这些产生变动的对象
  • 第四阶段并发清除(并行): 此阶段会将标记的对象进行清除,释放内存空间,此阶段也不会出现暂停。

因为CMS是使用标记-清除算法,我们要额外使用一个空闲列表来维护空间内存。
那为什么不用标记-整理而是用标记-清除呢?

因为CMS在清除数据的时候是并发清除,这时候用户线程还能使用活数据,如果这时候
我们改动内存的引用地址,用户线程就找不到之前的引用了,所以我们只能使用标记-清除,在改动活数据的情况下清除不可达对象。

CMS的优缺点
优点:并发收集、低延迟
缺点:
1)会产生内存碎片
2)无法处理浮动垃圾:因为我们标记是并发标记,那么用户线程可能会在这个阶段产生新垃圾对象,CMS无法对这些垃圾对象进行标记,会导致这些新垃圾对象没有被及时回收,只能等待下一次GC回收。

G1回收器(区域化分代)

因为G1是一个并行回收器,它把堆内存分割为很多不相关的区域(Region)(物理上不连续的)。使用不同的Region来表示Eden、幸存者o区,幸存者1区,老年代等。
G1 Gc有计划地避免在整个Java堆中进行全区域的垃圾收集。G1跟踪各个Region里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需时间的经验值),在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的Regiono由于这种方式的侧重点在于回收垃圾最大量的区间(Region),所以我们给G1一个名字:垃圾优先(Garbage First) 。在这里插入图片描述
为什么要设置H:
我们向堆中放大对象,一般放在老年代中,但是如果是短期存在的大对象,我们就会用一个H区来存放,如果这个对象一个H区不够放,就用连续的H区来存放,为了能找到连续的H区,有时候不得不启动Full Gc。G1的大多数行为都把H区作为老年代的一部分来看待。
s,.

使用的算法:
内存的回收是以region作为基本单位的。Region之间是复制算法,但整体上实际可看作是标记-压缩(Mark-Compact算法,两种算法都可以避免内存碎片。

可预测的停顿时间模型(即:软实时soft real-time)

G1 跟踪各个 Region里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需时间的经验值),在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的Region。保证了G1收集器在有限的时间内可以获取尽可能高的收集效率。
在这里插入图片描述


在这里插入图片描述

垃圾回收的三个环节

  • 年轻代GC
  • 老年代并发标记过程
  • 混合回收
    在这里插入图片描述
  • 当年轻代的Eden区用尽时开始年轻代回收过程,G1的年轻代收集阶段是一个并行的独占式收集器
  • 堆内存使用达到一定值(默认45%)时,开始老年代并发标记过程
  • 标记完成马上开始混合回收过程。对于一个混合回收期,G1 Gc从老年区间移动存活对象到空闲区间,这些空闲区间也就成为了老年代的一部分。和年轻代不同,老年代的G1回收器和其他GC不同,G1的老年代回收器不需要整个老年代被回收,一次只需要扫描/回收-小部分老年代的Region就可以了

一个Region不可能是孤立的,一个Region中的对象可能被其他任意Region中对象引用,判断对象存活时,是否需要扫描整个Java堆才能保证准确?

解决方法:

  • Remembered set来避免全局扫描:每个Region都有一个对应的Remembered set;
  • Reference类型数据写操作时,都会产生一个write Barrier暂时中断操作;
  • 然后检查将要写入的引用指向的对象是否和该Reference类型数据在不同的Region(其他收集器:检查老年代对象是否引用了新生代对象);
  • 通过cardTable把相关引用信息记录到引用指向对象的所在Region对应的Remembered set中;
  • 在GC根节点的枚举范围加入Remembered Set;就可以保证不进行全局扫描,也不会有遗漏。
    在这里插入图片描述

回收过程一(年轻代GC):

当Eden区满时才会触发年轻代垃圾回收,年轻代垃圾回收只会回收Eden区和Survivor区

首先G1停止应用程序的执行(Stop-The-World)G1创建回收集(collection set),回收集是指需要被回收的内存分段的集合,年轻代回收过程的回收集包含年轻代Eden区和survivor区所有的内存分段。

在这里插入图片描述
在这里插入图片描述
脏卡表队列作用:

Reset更新需要线程同步,所以开销会很大,因此不能实时更新,因此我们需要把引用对象被其他对象引用的关系放在一个脏卡表队列中,当年轻代回收的时候会进行STW,所以我们也正好把脏卡表队列中的值更新到Rset中,这样不仅没有涉及到开销问题,还可以保证Rset中的数据是准确的.

G1回收过程二:并发标记过程

在这里插入图片描述

G1回收过程二:混合回收

在这里插入图片描述
在这里插入图片描述

G1回收可选的过程四:Full Gc

在这里插入图片描述

总结:

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JVM——垃圾回收器 的相关文章

  • 在Java Servlet中获取通过jquery ajax发送的参数[重复]

    这个问题在这里已经有答案了 我在网上搜索这个主题 但找不到有效的示例 我会很高兴有人能给我帮助 这就是我测试的 ajax url GetJson type POST dataType json contentType application
  • 从 Android 函数更新 Textview

    有人可以告诉我如何从函数更新 Android Textview 控件吗 我在互联网上进行了深入搜索 看到很多人都问同样的问题 我测试了线程但无法工作 有人有一个简单的工作示例吗 例如 调用一个函数 在循环中运行多次 并且该函数在 TextV
  • java 拖放

    我尝试熟悉java中的拖放 但我发现的所有教程都是 让我生气 我想要的只是从 JList 包含在名为 UserPanel 的自制 JPanel 中 拖动 PublicUserLabel 并将其放入从 JTabbedPanel 继承的自制类中
  • Java:为什么.class文件中的方法类型包含返回类型,而不仅仅是签名?

    class 文件的常量池中有一个 NameAndType 结构 它用于动态绑定 该类可以 导出 的所有方法都被描述为 签名 返回类型 喜欢 getVector Ljava util Vector 当某些 jar 中方法的返回类型发生更改时
  • 二元运算符 >=、-、* 的错误操作数类型

    我无法弄清楚如何修复代码中不断出现的这些错误 import java util Scanner public class Unit02Prog1 public static void main String args Scanner inp
  • java中高效的输入流到字符串方法

    因此 我在 Java 中的 诚然非常简单 应用程序上运行探查器 令我惊讶的是 仅次于需要在时间上发出 HTTP 请求的方法的是我的方法 inputStreamToString方法 目前它的定义如下 public static String
  • 如何杀死 Java Future?

    我正在开发的服务使用 Future 来并行运行多个任务 每个任务最多可能需要一分钟才能完成 然而 外部库似乎有问题 因为在某些情况下 2 的时间 它不会返回 在这些情况下 我想给出 2 分钟的等待时间 如果还没有返回 我想杀死 future
  • 是否可以使用 Apache Tika 提取表信息?

    我正在寻找 pdf 和 MS Office 文档格式的解析器 以从文件中提取表格信息 当我看到 Apache Tika 时 正在考虑编写单独的实现 我能够从任何这些文件格式中提取全文 但我的要求是提取表格数据 我希望有 2 列采用键值格式
  • 在 doxygen 中使用 @see 或 @link

    我之前用 Javadoc 记录并使用了标签 see link or see foo and link foo 在我的描述中链接到其他课程 现在我尝试了doxygen 似乎这些标签不兼容 如果我运行 doxygen 完整的标签将被简单地解释为
  • 我的 Kafka 流应用程序刚刚退出,代码为 0,什么也不做

    为了尝试 Kafka 流 我这样做了 public static void main String args final StreamsBuilder builder new StreamsBuilder final Properties
  • 从字符串中删除重音符号

    Android 中有没有什么方法 据我所知 没有 java text Normalizer 可以从字符串中删除任何重音 例如 变成 eau 如果可能的话 我想避免解析字符串来检查每个字符 java text NormalizerAndroi
  • 在 Eclipse RCP 应用程序中禁用插件贡献

    我经常遇到这个问题 但尚未找到解决方案 每当我编写一个新的基于 Eclipse RCP 的应用程序并包含来自 Eclipse 平台的插件时 我都会 继承 其中一些插件的 UI 贡献 大多数贡献 菜单项 键盘快捷键 属性页 都很有用 但有时我
  • 如何使用 AffineTransform.quadrantRotate 旋转位图?

    我想旋转一个bitmap关于它的中心点 然后将其绘制成更大的图形上下文 位图是40x40 pixels 图形上下文是500x500 pixels 这就是我正在做的 BufferedImage bi new BufferedImage 500
  • 在 Tensorflow-lite Android 中将位图转换为 ByteBuffer(浮点)

    在用于图像分类的tensorflow lite android演示代码中 图像首先转换为ByteBuffer格式以获得更好的性能 这种从位图到浮点格式的转换以及随后到字节缓冲区的转换似乎是一个昂贵的操作 循环 按位运算符 float mem
  • 在 Spring MVC 中将请求写入文件

    我希望能够将整个请求写入 Spring MVC 控制器中的文件 我已尝试以下操作 但即使我使用大量参数发出 POST 请求 文件也始终为空 RequestMapping method RequestMethod POST value pay
  • ebean 映射到 BYTEA 的数据类型是什么?

    我有一个游戏 2 0 2 需要在数据库中存储一些文件的应用程序 我们使用 Ebean 作为 ORM 我相信我的数据库中需要一个 BYTEA 列来存储该文件 但我不确定在我的模型中使用什么数据类型 我应该使用某种Blob 或者只是一个byte
  • 使用 Hibernate Envers 的复合表

    我有一个带有复合表的应用程序 其中包含一个额外的列 一切正常 直到我们添加 Hibernate Envers Audited org hibernate MappingException 无法读取 no pack response Resp
  • junit4 使用特定测试方法创建测试套件

    在 junit4 中 我想执行来自不同类的特定测试方法 即想要使用来自不同类的特定测试方法创建一个测试套件 假设我有两门课 public class Test Login Test public void test Login 001 Sy
  • Axis2 的 wsdl2java 在 RPC/Encoded 样式 Web 服务上失败

    Axis2 有替代方案吗 或者让它工作的方式 例如不同的数据绑定 Retrieving document at Exception in thread main org apache axis2 wsdl codegen CodeGener
  • FetchType.LAZY 不适用于休眠中的 @ManyToOne 映射

    简而言之 我的 Child 类与 Parent 类之间存在多对一的关系 我想加载所有的孩子 而不必加载他们的父母详细信息 我的孩子班级是 Entity public class Child implements Serializable I

随机推荐

  • Go 编程学习路线

    安装IED vscode atom subl 插件安装错误总结 入门 go by example the way to go go web 编程 豆瓣 提升书籍 The Go Programming Language 2015 11 pdf
  • Oracle查看用户所在的表空间

    oracle 查看表空间有哪些表 select from dba tables where tablespace name 表空间名 注意表空间名大小写敏感 select table name tablespace name from us
  • linux的进程1:rootfs与linuxrc

    在内核启动的最后阶段启动了三个进程 进程0 进程0其实就是刚才讲过的idle进程 叫空闲进程 也就是死循环 进程1 kernel init函数就是进程1 这个进程被称为init进程 进程2 kthreadd函数就是进程2 这个进程是linu
  • 2023年6月电子学会Python等级考试试卷(四级)答案解析

    青少年软件编程 Python 等级考试试卷 四级 分数 100 题数 38 一 单选题 共25题 共50分 1 下列程序段的运行结果是 def s n if n 0 return 1 else return n s n 1 print s
  • Linux服务器EDAC CE memory read error

    之前在大数据集群中 有一台服务器的CPU占用总是莫名其妙飙高 就算执行简单任务也会耗费很长时间 且reboot不能解决问题 检查了各种可能的问题之后 最终在查看dmesg命令的设备信息时 发现大量如下的日志 1180532 573917 E
  • STL 小结

    看C STL一个月了 小结下这个阶段的学习所得 容器是以class template完成 内存管理师由memory pool完成 算法是由function template完成 仿函数 函数对象 是一种将operation 重载了的clas
  • SpringCloud整合Hystrix熔断器

    文章目录 SpringCloud整合Hystrix熔断器 1 什么是Hystrix 2 服务调用雪崩 3 线程隔离和服务降级 线程隔离原理 服务降级 4 实现Hystrix服务降级 导入springCloud的Hystrix依赖 注解启动类
  • rc=20 > Connect to SAP gateway failed

    这种错误 我是在一台用户的电脑上碰到的 解决方案很简单 把Computer Name换成英文 汗了许久
  • BUUCTF题目N1BOOK部分wp(持续更新)

    第九章 CTF之MISC章 两个部分的flag 附件 stego png 隐写了一个zip文件 zip文件里面是 2 jpg stego png 2 jpg stego png 用 StegSolve Data Extract BGR LS
  • leaflet 添加 wms

  • pytorch5-各种常用激活函数

    import matplotlib pyplot as plt import torch from torch import nn x torch linspace 6 6 10 sigmoid nn Sigmoid sigmoid激活函数
  • logback--基础--04--配置--appender

    logback 基础 04 配置 appender 代码位置 https gitee com DanShenGuiZu learnDemo tree master logback learn 1 根节点 lt configuration g
  • android Launcher学习总结

    一 Launcher功能介绍 Launcher简称HomeScreen 是android手机加载完毕后第一个启动的应用程序 它负责除应用本身操作外的所有操作 包括有几个桌面 点击应用程序图标启动应用程序 长时间按桌面出现上下文菜单 长按桌面
  • 骑士周游问题

    骑士周游问题 1 马踏棋盘问题 骑士周游问题 实际上是图的深度优先搜索 DFS 的应用 2 如果使用回溯 就是深度优先搜索 来解决 假如马儿踏了53个点 如图 走到了第53个 坐标 1 0 发现已经走到尽头 没办法 那就只能回退了 查看其他
  • python实现按键精灵找色点击功能,使用pywin32和Pillow库

    Python图片处理模块PIL pillow pywin32的主要作用 1 捕获窗口 2 模拟鼠标键盘动作 3 自动获取某路径下文件列表 4 PIL截屏功能 找色点击功能思路 抓取当前屏幕快照 指定一个坐标和颜色 如果坐标的颜色符合 则点击
  • 在Vue2中使用Swiper

    由于兼容性问题 使用的是Swiper4 首先是安装 npm i swiper 4 在组件中引入 import swiper dist js swiper import swiper dist css swiper css import Sw
  • css01

    1 css基础认知 CSS 叫 层叠样式表 用来 给html页面修改样式 可以让页面更美观 css的书写位置 内嵌式
  • C++:替换文本文件中的某些字符

    include
  • linux开机dracut界面_dracut 基本介绍

    dracut 维基 https dracut wiki kernel org index php Main Page http www 360doc com content 13 0428 09 12139495 281449877 sht
  • JVM——垃圾回收器

    JVM 垃圾回收器 按照工作模式分 可以分为并发式垃圾回收器和独占式垃圾回收器 并发式垃圾回收器与应用程序线程交替工作 以尽可能减少应用程序的停顿时间 独占式垃圾回收器 stop the world 一旦运行 就停止应用程序中的所有用 户线