[JVM]再聊 CMS 收集器

news2024/9/27 0:58:32

题目之所以是再聊,是因为以前聊过: [JVM]聊聊 CMS 收集器

最近又看了下这块的知识,打算把 CMS/标记-清除/GC Roots/引用 这些知识串起来
我依旧可能写的不是很好,降低下期待

GC 算法

CMS 是基于 标记-清除 算法来做的,那我们就先从 GC 算法开始聊

GC 算法有:

  • 标记-清除
    • 标记阶段: 从 GC Roots 对象开始遍历对象图,将所有可达对象进行标记
    • 清除阶段: 堆中未被标记的对象进行清除,释放内存空间
  • 标记-复制:
    • 标记阶段: 从 GC Roots 对象开始遍历对象图,将所有可达对象进行标记
    • 复制阶段: 将所有标记的对象从 From 指针指向的区域,复制到 To 指针指向的区域,同时更新对象引用
    • 回收阶段: 清除未被标记的对象,同时更新 From 指针和 To 指针指向的区域,保持 From 指针指向的区域为空
  • 标记-整理:
    • 标记阶段: 从 GC Roots 对象开始遍历对象图,将所有可达对象进行标记
    • 整理阶段: 将所有标记的对象向一端移动,然后将未被标记的内存空间释放

标记-清除算法有两个缺点: 1 执行效率不稳定:大量对象需要大量被回收时,会导致标记 & 清除效率变低; 2 内存碎片化
标记-复制算法解决了内存碎片化的问题,但它是以牺牲空间来优化的(因为有一部分空间要留出来复制用)
标记-整理算法也解决了内存碎片化的问题,但它是以牺牲时间来优化的(因为要花时间将标记对象移动到一起)

CMS 基于 标记-清除 算法来实现的,那就会有一个无法避免的缺点: 会有大量的空间碎片

CMS 进行垃圾回收时的整个过程

接下来聊一聊 CMS 进行垃圾回收时的整个过程,其实也就是 4 个过程啦:

  • 初始标记: 标记 GC Roots 能直接关联到的对象,此时垃圾收集线程是独占的,不会和用户线程一起运行,会发生 stop the world 现象,不过整个过程时间很短
  • 并发标记: 从 GC Roots 的直接关联对象开始遍历整个对象图,耗时比较长,不过看名字也看出来了,"并发,并发"嘛,此时的垃圾收集线程是和用户线程一起进行的
  • 重新标记: 是为了修正并发标记期间产生变动的记录,这个过程相对于初始标记来说,耗时是挺长的,但是相对于并发标记来说,耗时还是挺短的,此时垃圾收集线程也是独占的,会发生 stop the world 对象
  • 并发清除: 清理删除标记的对象,此时不需要移动对象,所以会和用户线程一起工作

什么是 GC Roots

在聊 GC 算法时,标记阶段都是从 GC Roots 开始的
那么,什么是 GC Roots?
要聊 GC Roots 的话,就需要来聊聊: 引用计数法

首先,垃圾收集器回收的一定是程序没有在用的对象,那它应该怎么判断这个对象有没有在用,能不能被回收呢?
可以在对象中添加一个引用计数器,如果这个对象被引用了,引用计数器就加一;如果引用失效了,引用计数器就减一
这样回收的时候,看看哪些计数器计数为 0 ,就可以回收了
此时就会有一个问题: A 引用了 B , B 引用了 A ,它俩在循环引用彼此,但除此之外,没有别的对象引用了
A,B 的引用计数器都为 1 ,就不会回收

引用计数法看来就不是很完美嘛,为了优化这个问题,就有了 GC Roots(可达性分析)
它的做法是: 一系列被称为 "GC Root"根对象作为起始节点集,根据引用关系向下探索
这样的话,虽然 A,B 在循环引用,但是没有任何一个 GC Root 可以达到它们,此时它们就会被回收

什么可以被称为 “GC Root” 呢?

  • 在虚拟机栈(栈帧中的本地变量表)中引用的对象,譬如各个线程被调用的方法堆栈中使用到的参数/局部变量/临时变量等
  • 在方法区中类静态属性引用的对象,譬如 Java 类的引用类型静态变量
  • 在方法区中常量引用的对象,譬如字符串常量池( String Table )里的引用
  • 在本地方法栈中 JNI (即通常所说的 Native 方法)引用的对象
  • Java 虚拟机内部的引用,如基本数据类型对应的 Class 对象,一些常驻的异常对象(比如 NullPointExcepiton/OutOfMemoryError)等,还有系统类加载器
  • 所有被同步锁( synchronized 关键字)持有的对象
  • 反映 Java 虚拟机内部情况的 JMXBean/JVMTI 中注册的回调、本地代码缓存

别惊讶了,上面那一段是我直接从<深入理解 Java 虚拟机>这本书里,直接复制过来的
其实来看下 Java 虚拟机运行时数据区,就比较容易理解了
在这里插入图片描述

  • 程序计数器: 当前线程所执行的字节码的行号指示器
  • 虚拟机栈: 用于存储 局部变量表/操作数栈/动态连接/方法出口 等信息
  • 本地方法栈: 与虚拟机栈所发挥的作用是非常相似的,区别是虚拟机栈为虚拟机执行 Java 方法服务,而本地方法栈则是为虚拟机使用到的本地( Native )方法服务
  • 堆: 此内存区域的唯一目的就是存放对象实例, Java 世界里“几乎”所有的对象实例都在这里分配内存,垃圾收集器管理的内存区域说的就是堆了
  • 方法区: 用于存储已被虚拟机加载的 类型信息/常量/静态变量/即时编译器编译后的代码缓存 等数据
    • 运行时常量池: 是方法区的一部分, Class 文件中除了有类的版本/字段/方法/接口等描述信息外,还有一项信息是常量池表,用于存放编译期生成的各种字面量与符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中

对应着 GC Roots 来看运行时数据区,大部分就能对应上了,不外乎 虚拟机栈中引用的对象/本地方法栈中 native 方法引用的对象/方法区中类静态属性引用的对象/方法区中常量引用的对象

引用

在聊 GC Roots 时,提到了引用,这里扩展下
引用分为:

  • 强引用: 只要存在,就不会回收
  • 软引用: 还有用,但非必须对象,在内存溢出异常前,会被列进回收范围内,进行第二次回收
  • 弱引用: 非必须对象,不管内存是否足够,都会回收
  • 虚引用: 为了能在这个对象被回收时,有系统通知

以上,感谢您的阅读~

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

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

相关文章

一篇博客教会你使用Docker部署Redis哨兵

文章目录 主数据库配置文件启动实例容器虚拟IP 从数据库配置文件启动实例 主从数据库查看主数据库查看从数据库 哨兵配置文件启动哨兵查看哨兵 哨兵机制哨兵选举选举日志重启主数据库 今天我们学习使用 Docker 部署 Redis 的主从复制&#xff0c;并部署 Redis 哨兵&#xff0c;…

Linux学习之grub配置文件介绍

grub配置文件 /etc/default/grub这个文件里边有一些简单的grub配置。 可以看到/etc/default/grub文件里有GRUB_CMDLINE_LINUX"crashkernelauto rhgb quiet idlehalt biosdevname0 net.ifnames0 consoletty0 consolettyS0,115200n8 noibrs nvme_core.io_timeout429496729…

全网独家--【图像色彩增强】方法梳理和问题分析

文章目录 图像增强图像色彩增强问题可视化比较 难点色彩空间大&#xff0c;难以准确表征&#xff1f;不同场景差异大&#xff0c;难以自适应&#xff1f;计算量大&#xff0c;但应用场景往往实时性要求高&#xff1f; 方法传统方法深度学习逐像素预测3D LUT模仿ISP 个人思考批判…

2.数据的类型、数据的输入输出

2.数据的类型、数据的输入输出 2.1 数据类型-常量-变量(整型-浮点-字符)2.1.1 数据类型2.1.2 常量2.1.3 变量2.1.4 整型类型2.1.5 浮点型数据2.1.6 字符型数据字符型常量字符型变量 2.1.7 字符串型常量 2.2 混合运算-printf讲解 2.1 数据类型-常量-变量(整型-浮点-字符) 2.1.1…

shell脚本怎么获取当前脚本名称(获取脚本文件名)$(basename “$0“)(basename命令:去除字符串路径部分、去除后缀)

文章目录 shell脚本如何获取当前执行脚本名称解释&#xff1a;$(basename "$0")$0&#xff08;当前脚本的名称&#xff0c;带脚本与工作目录之间的相对路径&#xff09;basename&#xff08;去除字符串路径部分&#xff09;示例 拓展&#xff1a;basename命令的完整用…

项目引入多个连接池,导致使用其他连接池,maven分析学习

第一步在命令行中执行 mvn dependency:tree > excludeParentstart.log如果你的settings文件不是项目使用的setting配置&#xff0c;那么就使用下面的命令 mvn -gs 你的路径/apache-maven-3.8.2/conf/settings-person.xml dependency:tree > excludeParentstart.log然后…

Spring学习---上篇

文章目录 1、Spring1.1、简介1.2、优点1.3、Spring的组成1.4、拓展 2、IOC理论推导3、IOC的本质3.1、IOC概念3.2、IoC是Spring框架的核心内容 3、HelloSpring3.1、实现3.2、思考 4、IOC创建对象的方式5、Spring配置5.1、别名&#xff08;alias&#xff09;5.2、Bean的配置5.3、…

Multi-class classification without multi-class labels (ICLR 2019)

Multi-class classification without multi-class labels (ICLR 2019) 摘要 这项工作提出了针对多分类的新策略&#xff0c;不需要具体的类别标签&#xff0c;取而代之是利用样本之间的两两相似度&#xff0c;这是一种弱化的标注方式。所提方法称作元分类学习&#xff0c;为两…

ModaHub魔搭社区:向量数据库Milvus使用 MySQL 管理元数据教程

目录 使用 MySQL 管理元数据 常见问题 数据管理相关博客 使用 MySQL 管理元数据 Milvus 默认使用 SQLite 作为元数据后台管理服务&#xff0c;SQLite 内嵌于 Milvus 进程中&#xff0c;无需启动额外服务。但是在生产环境中&#xff0c;基于可靠性的考虑&#xff0c;我们强烈…

【数据库管理】十分钟了解啥是三级封锁协议、X锁和S锁

一.为什么要用锁 在多用户共享系统中&#xff0c;许多事务可能同时对同一数据进行操作&#xff0c;称为“并发操作”&#xff0c;此时数据库管理系统的并发控制子系统负责协调并发事务的执行&#xff0c;保证数据库的完整性不受破坏&#xff0c;同时避免用户得到不正确的数据。…

Spring框架概括

spring是什么&#xff1f; Spring是2003年兴起的&#xff0c;它是一个轻量级的&#xff0c;非侵入式的IOC和AOP的一站式框架&#xff0c;为简化企业级应用开发。 它的特点&#xff1a; 轻量级&#xff1a;指的是核心jar包比较小的。 非侵入式的&#xff1a;框架代码不会侵入…

Java——《面试题——MQ篇》

前文 java——《面试题——基础篇》 Java——《面试题——JVM篇》 Java——《面试题——多线程&并发篇》 Java——《面试题——Spring篇》 Java——《面试题——SpringBoot篇》 Java——《面试题——MySQL篇》​​​​​​ Java——《面试题——SpringCloud》 Java…

KingFusion3.6是什么?

哈喽&#xff0c;大家好&#xff0c;我是雷工&#xff01; 今天继续学习KingFusion3.6&#xff0c;以下为学习笔记。 一、KingFusion3.6简介 1、管控一体化全组态平台KingFusion3.6是一款面向工业企业执行层的生产信息化管理系统。 2、KingFusion3.6基于“全组态”技术&#…

使用ROS功能包camera_calibration进行单目相机和双目相机的内参和外参标定

1.概述 本文总结使用ROS标定单目和双目相机的过程&#xff0c;同时提供生成棋盘格文件的方法。 参考链接&#xff1a; [1]使用ros标定相机的内参和外参 [2]ROS下采用camera_calibration进行双目相机标定 2.生成棋盘格文件 棋盘格可以自己买一个&#xff0c;或者打印一个粘在…

日本团队推出 AI 恋爱游戏:主角穿什么,玩家说了算

女主穿什么&#xff0c;还能由玩家决定&#xff1f;&#xff01; IT之家6月25日消息&#xff0c;来自日本的一个两人团队近期发布了一段视频&#xff0c;展示了一款正在开发中的基于 AI 的恋爱游戏。 在游戏初期&#xff0c;女主角会以黑色剪影的形式出现&#xff0c;针对女主…

紫云谷游记

先说重点&#xff0c;TLNR 1.早点去&#xff0c;方便找地方停车&#xff0c;坐渡船不用排队太久。 2.景区里的饭没外面的好吃。 3.溯溪回来再在游泳池游泳&#xff0c;溯溪凉快&#xff0c;游泳太晒。 4.溯溪真的好爽。 导航&#xff1a; 紫云谷乘船码头停车场 景区介绍就不多说…

常见电池容量概念

嵌入式软件做产品一定要考虑功耗问题 功耗是多少&#xff0c;装上电池能用多久。 1、毫安时和毫瓦时 毫安时&#xff08;mAh&#xff09;和毫瓦时&#xff08;mWh&#xff09;是两个不同的物理量&#xff0c;它们分别表示电量和能量的度量单位。下面图片搜18650得到不同结果&…

Elasticsearch介绍与应用

Elasticsearch介绍与应用 Elasticsearch的官方文档。 Elasticsearch官网参考文档&#xff1a;https://www.elastic.co/guide/index.html Elasticsearch官方下载地址&#xff1a;https://www.elastic.co/cn/downloads/elasticsearch mvnrepository依赖库地址&#xff1a;http…

你对工作队列了解多少?Linux中断处理中的workqueue介绍

Linux中断处理中的workqueue介绍 一、workqueue的作用及在Linux中断处理中的应用1.1、workqueue的概述1.2、workqueue在Linux中断处理中的作用 二、workqueue的实现原理2.1、工作队列和工作者线程的关系2.2、工作队列的创建和销毁2.3、工作者线程的创建和销毁2.4、扩展知识&…

2023年的今天,谨慎进入网络安全行业

前言 2023年的今天&#xff0c;慎重进入网安行业吧&#xff0c;目前来说信息安全方向的就业对于学历的容忍度比软件开发要大得多&#xff0c;还有很多高中被挖过来的大佬。 理由很简单&#xff0c;目前来说&#xff0c;信息安全的圈子人少&#xff0c;985、211院校很多都才建…