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

news2024/10/5 21:16:48

目录

  • 垃圾回收器
    • 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.coloradmin.cn/o/1127240.html

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

相关文章

电子宣传册制作攻略,打造完美视觉效果

随着互联网的普及,电子宣传册已成为企业宣传的重要手段之一。但是你知道如何制作一份吸引人的电子宣传册,打造完美的视觉效果呢? 我们只需利用FLBOOK这个在线电子期刊制作平台,就可以打造出完美视觉效果的电子宣传册,操…

postgres和postgis下载链接

PostGIS Index of /postgis/windows/ postgres PostgreSQL 10.9 (64-bit) Download arcgis支持的版本 适用于 PostgreSQL 的 ArcGIS 11.1 和 ArcGIS Pro 3.1 要求 适用于—ArcGIS Enterprise | ArcGIS Enterprise 文档 arcgis如何连接 ArcMap 中的数据库连接—ArcMap | 文…

亚马逊添加购物车和收藏有什么区别

亚马逊的添加购物车和收藏是两个不同的功能,它们在用户行为和用途上有明显的区别: 1、添加购物车(Add to Cart): 当用户点击"添加到购物车"按钮时,所选商品将被放入他们的购物车,而…

Power BI 傻瓜入门 7. 清理、转换和加载数据

本章内容包括 根据异常、属性和数据质量问题确定清理需求解决数据类型、值、键、结构和查询之间的不一致在数据加载之前根据查询和命名约定对数据进行流化处理 要进行任何数据清理和转换,您的组织需要分析师、工程师和侦探。这里的想法是,在进入系统之…

严重内卷的电商直播还有机会吗?教你如何在电商直播中脱颖而出!

用行业内的一句话来讲:如今的电商直播带货,没有最卷只有更卷! 过去,电商直播带货只是中规中矩的“叫卖式”直播。随着“全民直播带货”的潮流兴起,电商直播带货行业的竞争变得越来越激烈:同质化的内容不断…

ADC架构种类说明_笔记

ADC架构种类说明 FLASH_架构ADC 可达GHz级别Pipeline_ADC架构SAR ADC架构![在这里插入图片描述](https://img-blog.csdnimg.cn/d42b65568b6648ec92b04e7b6c53fa0d.png?x-oss-processimage/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Ieq5bCP5ZCD5aSa,size_20,col…

怎么下载微信视频号视频?

你是否曾经在浏览视频号时看到了一些精彩的视频号,希望能够保存下来,但却不知道如何下载?别担心!本篇文章将为你介绍一个方便易用的视频号下载工具,让你轻松保存喜欢的视频号视频!犀牛下载是一款专门为微信…

drf-分页,coreapi自动生成接口文档

目录 分页 视图类继承ListAPIView的分页具体使用方法 # 第一种PageNumberPagination页码分页 # 第二种LimitOffsetPagination偏移分页 # 第三种CursorPagination游标分页 视图类的使用 视图类继承APIView或GenericAPIView的分页使用 coreapi 如何写好接口文档 自动生…

众和策略可靠吗?A股构筑“市场底” 卫星互联网和5.5G逆势走强

可靠 周一A股三大指数低开低走,午后加快下探并创出今年以来新低,尾盘跌幅略有收窄。截至收盘,上证综指收于2939.29点,跌落1.47%;深证成指收于9425.98点,跌落1.51%;创业板指收于1864.91点&#…

AtCoder Beginner Contest 325 题解 A-E

目录 A - Takahashi sanB - World MeetingC - SensorsD - Printing MachineE - Our clients, please wait a moment A - Takahashi san 原题链接 题目描述 给你两个字符串,将第二个字符串改为san后与第一个字符串一起输出 public static void solve() throws IOExc…

spring懒加载

简介 Spring默认会在容器初始化的过程中,解析xml或注解,创建配置为单例的bean并保存到一个map中,这样的机制在bean比较少时问题不大,但一旦bean非常多时,spring需要在启动的过程中花费大量的时间来创建bean &#xff0…

Postman笔记

文章目录 1.安装2.简介和使用流程3 postman使用3.1 测试集与HTTP请求发送HTTP请求和分析响应数据 3.2 发送HTTP请求和分析响应数据3.3 Postman中请求体提交方式3.4 Postman使用之接口测试3.5 使用Postman新建一个mock服务3.6 请求数据的参数化3.7 断言与脚本导出 1.安装 官网地…

外汇天眼:过度交易是大忌,交易不是越多越好!

过度交易是交易中的大忌,因为交易并不是越多越好。为什么我们倾向于将交易失败归因于心态呢?这可能是因为我们认为一笔交易成功和失败的概率都是50%,从而让人们误以为他们具备盈利的能力。然而,如果我们具备盈利的能力&#xff0c…

【Java基础学习打卡21】流程控制

目录 前言一、流程控制的重要性二、流程控制结构1.顺序结构2.分支结构3.循环结构 三、顺序结构总结 前言 无论是哪种编程语言,都会提供流程控制结构:顺序结构、分支结构和循环结构。其实计算机之所以能够完成很多自动化的任务目标,因为它可以…

Flutter笔记:图片的 precacheImage 函数

Flutter笔记 图片的 precacheImage 函数 作者:李俊才 (jcLee95):https://blog.csdn.net/qq_28550263 邮箱 :291148484163.com 本文地址:https://blog.csdn.net/qq_28550263/article/details/134004572 【简…

执行 SQL 响应比较慢,你有哪些排查思路?

排查思路 如果执行 SQL 响应比较慢,我觉得可能有以下 4 个原因: 第 1 个原因:没有索引或者导致索引失效。 第 2 个原因:单表数据量数据过多,导致查询瓶颈第 3 个原因:网络原因或者机器负载过高。 第 4 个原…

JAVA-编程基础-11-02-文件流

Lison <dreamlison163.com>, v1.0.0, 2023.05.07 JAVA-编程基础-11-02-文件流 文章目录 JAVA-编程基础-11-02-文件流File 构造方法File 常用方法获取功能的方法**绝对路径和相对路径****判断功能的方法****创建、删除功能的方法**目录的遍历递归遍历 RandomAccessFile*…

LeetCode66——加一

LeetCode66——加一 题目描述&#xff1a; 给定一个由 整数 组成的 非空 数组所表示的非负整数&#xff0c;在该数的基础上加一。 最高位数字存放在数组的首位&#xff0c; 数组中每个元素只存储单个数字。你可以假设除了整数 0 之外&#xff0c;这个整数不会以零开头。 示例…

904. Fruit Into Baskets

904. Fruit Into Baskets 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;参考代码&#xff1a; 原题链接&#xff1a; 904. Fruit Into Baskets https://leetcode.cn/problems/fruit-into-baskets/ 完成情况&#xff1a; 解题思路&#xff1a; 连续数组 -…

Unity BatchRendererGroup 在低端设备上也实现高帧率

在这篇文章中&#xff0c;我们描述了一个小型射击游戏样本&#xff0c;它可以动画和渲染几个交互式对象。许多演示只针对高端pc&#xff0c;但这里的目标是在使用GLES 3.0的廉价手机上实现高帧率。这个例子使用了BatchRendererGroup, Burst编译器和c#作业系统。它运行在Unity 2…