jvm垃圾回收算法有哪些及原理

目录

  • 垃圾回收器
    • 1 Serial收集器
    • 2 Parallel收集器
    • 3 ParNew收集器
    • 4 CMS收集器
    • 5 G1回收器
    • 三色标记算法
      • 标记算法的过程
      • 三色标记算法缺陷
        • 多标
        • 漏标

垃圾回收器

垃圾回收机制,我们已经知道什么样的对象会成为垃圾。对象回收经历了什么——垃圾回收算法。那么谁来负责回收垃圾呢?

1 Serial收集器

-XX:+UseSerialGC -XX:+UseSerialOldGC

单线程执⾏垃圾收集,收集过程中会有较⻓的STW(stop the world),在GC时⼯作线程不能⼯作。虽然STW较⻓,但简单、直接。

新⽣代采⽤复制算法,⽼年代采⽤标记-整理算法。

在这里插入图片描述

由于Serial垃圾回收器是单线程的,因此它的优点是简单且占用资源较少;它适用于小型应用程序,例如移动应用程序和桌面应用程序。

2 Parallel收集器

-XX:+UseParallelGC,-XX:+UseParallelOldGC

使⽤多线程并行进⾏GC,会充分利⽤cpu,但是依然会有stw,这是jdk8默认使⽤的新⽣代和⽼年代的垃圾收集器。充分利⽤CPU资源,吞吐量⾼。

新⽣代采⽤复制算法,⽼年代采⽤标记-整理算法。

在这里插入图片描述

Parallel垃圾回收器适用于中等大小的应用程序,特别是那些需要高吞吐量的应用程序,例如: Web应用程序和大规模企业应用程
序。

3 ParNew收集器

-XX:+UseParNewGC

⼯作原理和Parallel收集器⼀样,都是使⽤多线程进⾏GC,但是区别在于ParNew收集器可以和CMS收集器配合⼯作。主流的方案:

ParNew收集器负责收集新生代,CMS负责收集老年代。

在这里插入图片描述

4 CMS收集器

-XX:+UseConcMarkSweepGC

⽬标:尽量减少stw的时间,提升⽤户的体验。真正做到gc线程和⽤户线程⼏乎同时⼯作。CMS采⽤标记-清除算法。

此处标记的是有用的对象。

  • 初始标记:暂停所有的其他线程(STW),并记录gc roots直接能引⽤的对象。

    例:线程栈帧的局部变量表中有个引用指向堆空间对象A,堆空间变量又引用了另一个对象B,则只记录A,不算B。

  • 并发标记:从GC Roots的直接关联对象开始遍历整个对象图的过程,这个过程耗时较⻓但是不需要STW,可以与应用线程⼀起并发运⾏。这个过程中,⽤户线程和GC线程并发,可能会有导致已经标记过的对象状态发⽣改变,所以下一步需要重新标记

    最后一句话是说会造成标记的遗漏:

    在这里插入图片描述

  • 重新标记:为了修正并发标记期间因为⽤户程序继续运⾏⽽导致标记产⽣变动的那⼀部分对象的标记记录,这个阶段的停顿时间⼀般会⽐初始标记阶段的时间稍⻓,远远比并发标记阶段时间短。主要⽤到三⾊标记⾥的算法做重新标记。

  • 并发清理:开启⽤户线程,同时GC线程开始对未标记的区域做清扫。这个阶段如果有新增对象会被标记为黑色不做任何处理。(最终被标记为白色的都是垃圾)

  • 并发重置:重置本次GC过程中的标记数据。

在这里插入图片描述

总结:

  • 这几步中,最费时间的是并发清理,所以采用了并发处理
  • 初始标记和重新标记两处采用STW形式,因为标记的速度很快
  • 重新标记采用STW模式,因为是最后一步标记,要确保标记到的必须都是用到的

5 G1回收器

用于大对象的回收,且jdk8版本对G1不是很完整

三色标记算法

标记算法的过程

再上述cms收集器中,采用到的算法就是三色标记法。

三色标记法会将内存中的对象分为白、灰、黑三种颜色,具体标记过程如下:

  1. 根据可达性分析算法,从 GC Roots 开始进行遍历访问。初始状态,所有的对象都是白色的,只有 GC Roots 是黑色的。

    在这里插入图片描述

  2. 初始标记阶段,GC Roots 标记直接关联对象置为灰色

    在这里插入图片描述

  3. 并发标记阶段,扫描整个引用链。

    • 没有子节点的话,将本节点变为黑色。

    • 有子节点的话,则当前节点变为黑色,子节点变为灰色。
      在这里插入图片描述

  4. 重复并发标记阶段,直至灰色对象没有其它子节点引用时结束。
    在这里插入图片描述
    在这里插入图片描述

扫描完成,此时黑色对象就是存活的对象,白色对象就是已消亡可回收的对象。

即(A、D、E、F、G)可达也就是存活对象,(B、C、H)不可达可回收的对象。

最终三种颜色对应的状态如下:
在这里插入图片描述

三色标记算法缺陷

三色标记算法,由于在并发标记阶段的时候,因为用户线程与 GC 线程同时运行,有可能会产生多标或者漏标

多标

假设已经遍历到 E(变为灰色了),此时应用执行了 objD.fieldE = null (D → E 的引用断开)。
在这里插入图片描述

D → E 的引用断开之后,E、F、G 三个对象不可达,应该要被回收的。然而因为 E 已经变为灰色了,其仍会被当作存活对象继续遍历下去。最终的结果是:这部分对象仍会被标记为存活,即本轮 GC 不会回收这部分内存。

这部分本应该回收但是没有回收到的内存,被称之为浮动垃圾。浮动垃圾并不会影响应用程序的正确性,只是需要等到下一轮垃圾回收中才被清除。

另外,针对并发标记开始后的新对象,通常的做法是直接全部当成黑色,本轮不会进行清除。这部分对象期间可能会变为垃圾,这也算是浮动垃圾的一部分。

漏标

假设 GC 线程已经遍历到 E(变为灰色了),此时应用线程先执行了:

var G = objE.fieldG; objE.fieldG = null; // 灰色E 断开引用 白色G objD.fieldG = G; // 黑色D 引用 白色G

在这里插入图片描述

此时切回到 GC 线程,因为 E 已经没有对 G 的引用了,所以不会将 G 置为灰色;尽管因为 D 重新引用了 G,但因为 D 已经是黑色了,不会再重新做遍历处理。

最终导致的结果是:G 会一直是白色,最后被当作垃圾进行清除。这直接影响到了应用程序的正确性,是不可接受的。

漏标只有同时满足以下两个条件时才会发生:

  • 一个或者多个黑色对象重新引用了白色对象;即黑色对象成员变量增加了新的引用。
  • 灰色对象断开了白色对象的引用(直接或间接的引用);即灰色对象原来成员变量的引用发生了变化。

也有方法可以解决:

需要在上面三个步骤中任意一个中,将对象 G 记录起来,然后作为灰色对象再进行遍历即可。比如放到一个特定的集合,等初始的 GC Roots 遍历完(并发标记),再重新标记阶段对该集合的对象遍历即可(重新标记)。

var G = objE.fieldG; // 1.读objE.fieldG = null; // 2.写objD.fieldG = G; // 3.写

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CodeFormer和GFPGAN的本地部署与效果对比

CodeFormer和GFPGAN是两个图片人脸修复的开源程序,两个程序不相伯仲,效果都非常棒,在stable diffusion中这两个插件都有集成进去!我们今天就将这两个程序的本地独立安装和使用方法记录一下! CodeFormer github主页地址…

单片机设计基于STM32的空气净化器设计

**单片机设计介绍,1615[毕设课设]基于STM32的空气净化器设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图pcb设计图 五、 程序六、 文章目录 一 概要 此设计资料主要包含原理图、PCB、源程序、元器件清等资料, 二、功能设计 设计思路 …

基于C/C++的UG二次开发流程

文章目录 基于C/C的UG二次开发流程1 环境搭建1.1 新建工程1.2 项目属性设置1.3 添加入口函数并生成dll文件1.4 执行程序1.5 ufsta入口1.5.1 创建程序部署目录结构1.5.2 创建菜单文件1.5.3 设置系统环境变量1.5.4 制作对话框1.5.5 创建代码1.5.6 部署和执行 基于C/C的UG二次开发…

java 通用导出接口

每个功能导出文件都单独写接口太过繁琐,出于方便大致讲讲通用导出功能的实现。 导出文件配置表,该表保存导出dto和导出文件名的对应关系等信息: TableName(value "SIMPLE_COMMON_EXPORT_TAB") public class SimpleCommonExportT…

【Sentinel】Sentinel簇点链路的形成

说明 一切节点的跟是 machine-root,同一个资源在不同链路会创建多个DefaultNode,但是在全局只会创建一个 ClusterNode machine-root/\/ \EntranceNode1 EntranceNode2/ \/ \DefaultNode(nodeA) DefaultNode(nodeA)|…

QGIS003:【04地图导航工具栏】-地图显示、新建视图、时态控制、空间书签操作

摘要:QGIS地图导航工具栏包括平移地图、居中显示、放大、缩小、全图显示、缩放到选中要素、缩放到图层、缩放到原始分辨率、上一视图、下一视图、新建地图视图、新建3D地图视图、新建空间书签、打开空间书签、时态控制面板、刷新等选项,本文介绍各选项的…

Zynq UltraScale+ XCZU9EG 纯VHDL解码 IMX214 MIPI 视频,2路视频拼接输出,提供vivado工程源码和技术支持

目录 1、前言免责声明 2、我这里已有的 MIPI 编解码方案3、本 MIPI CSI2 模块性能及其优越性4、详细设计方案设计原理框图IMX214 摄像头及其配置D-PHY 模块CSI-2-RX 模块Bayer转RGB模块伽马矫正模块VDMA图像缓存Video Scaler 图像缓存DP 输出 5、vivado工程详解PL端FPGA硬件设计…

智慧公厕:打造更美好的城市生活环境

在信息技术迅猛发展的今天,智慧公厕作为一种创新的城市管理模式,正逐渐受到人们的关注。以物联网、大数据、人工智能为基础,智慧公厕正逐步改变传统公厕的面貌,为城市居民提供更便捷、舒适的公共服务。本文将以智慧公厕源头厂家广…

数据结构初阶——时间复杂度

朋友们我们又见面了,今天我们来学习数据结构的时间复杂度,在讲数据结构之前,大家可能只知道我们学习的是数据结构,但是还是不知道数据结构的具体定义,其实就是在内存上的数据。然后我们就像通讯录一样对它进行增删查改…

SQL server中:常见问题汇总(如:修改表时不允许修改表结构、将截断字符串或二进制数据等)

SQL server中:常见问题汇总 1.修改表时提示:不允许修改表结构步骤图例注意 2.将截断字符串或二进制数据。3.在将 varchar 值 null 转换成数据类型 int 时失败。4.插入insert 、更新update、删除drop数据失败,主外键FOREIGN KEY 冲突5.列不允许…

SpringAOP源码解析之advice构建排序(二)

上一章我们知道Spring开启AOP之后会注册AnnotationAwareAspectJAutoProxyCreator类的定义信息,所以在属性注入之后initializeBean的applyBeanPostProcessorsAfterInitialization方法执行的时候调用AnnotationAwareAspectJAutoProxyCreator父类(AbstractAutoProxyCre…

三步,金蝶K3的数据可视化了

数据可视化的一大特点就是“一图胜千言”,没什么能比图表更直观展现数据的了。那,金蝶K3系统上那海量数据能不能也做成数据可视化报表?操作复杂吗,难度大吗? 换了别的软件来做,操作多、难度大是板上钉钉&a…

(ubuntu)安装nginx

文章目录 前言回顾Linux命令在线安装:相关命令:相关路径常用配置: 卸载nginxbug相关: 前言 提示:别再问我的规划是什么了:呼吸,难道不算一个吗? --E.M齐奥朗 回顾Linux命令 # 查看当前进程的所…

pdf误删恢复如何恢复?分享4种恢复方法!

如何将pdf误删恢复?使用电脑的时候,经常会需要使用到pdf文件,但是有时候,因为一些操作上的失误,我们会丢失一些重要的文件。如果你不小心将pdf误删了,该如何进行恢复呢? PDF文件丢失的原因可以…

Jenkins部署失败:JDK ‘jdk1.8.0_381‘ not supported to run Maven projects

Jenkins部署报错:JDK ‘jdk1.8.0_381’ not supported to run Maven projects提示使用的jdk有问题,启动的jdk版本不能满足项目启动。 登录Jenkins管理页面,系统管理——全局工具配置——JDK安装配置满足条件的JDK版本,保存配置&…

YOLOv7改进:新颖的上下文解耦头TSCODE,即插即用,各个数据集下实现暴力涨点

💡💡💡本文属于原创独家改进:上下文解耦头TSCODE,进行深、浅层的特征融合,最后再分别输入到头部进行相应的解码输出,实现暴力暴力涨点 上下文解耦头TSCODE| 亲测在多个数据集实现暴力涨点,对遮挡场景、小目标场景提升也明显; 收录: YOLOv7高阶自研专栏介绍: …

零售数据分析模板分享(通用型)

零售数据来源多,数据量大,导致数据的清洗整理工作量大,由于零售的特殊性,其指标计算组合更是多变,进一步导致了零售数据分析工作量激增,往往很难及时分析数据,发现问题。那怎么办?可…

模仿企业微信界面

备注&#xff1a;未实现相关功能&#xff0c;仅模仿界面&#xff0c;不能作为商业用途&#xff0c;若有侵权&#xff0c;请联系删除。 <Window x:Class"模仿企业微信界面.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"…

CVE-2023-46227 Apache inlong JDBC URL反序列化漏洞

项目介绍 Apache InLong&#xff08;应龙&#xff09;是一站式、全场景的海量数据集成框架&#xff0c;同时支持数据接入、数据同步和数据订阅&#xff0c;提供自动、安全、可靠和高性能的数据传输能力&#xff0c;方便业务构建基于流式的数据分析、建模和应用。 项目地址 h…

Linux系统安装redis并配置为服务

一、Linux环境 1、下载 官网提供的源码下载地址&#xff1a; https://github.com/redis/redis/archive/7.0.5.tar.gz 2、将源码上传至服务器 3、解压缩 # 将解压缩后的文件放置在同目录的source文件夹下 tar -zxvf redis-7.0.5.tar.gz -C ./source4、编译安装 对源码进行编…