可达性分析、三色标记、新生代、老年代的关系是什么

这篇具有很好参考价值的文章主要介绍了可达性分析、三色标记、新生代、老年代的关系是什么。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        jvm提供了垃圾回收器进行垃圾回收,垃圾回收器的职责就是回收内存中不再被引用的对象,以便释放内存。垃圾回收器利用可达性分析算法去分析哪些对象需要被回收,可达性分析算法是这样的:首先一些对象被定义为gc roots,然后沿着这些gc roots对象的引用链往下查找,无法通过gc roots的引用链被查找到的对象即为不可达对象。三色标记是可达性分析算法的一种实现,它包含三种颜色:白色、灰色和黑色,不同颜色有不同的意义,在三色标记结束之后,gc将去回收白色的对象。我们知道,在jvm的内存模型中,堆内存是gc回收的重要区域,因为大部分的对象都是保存在堆中的,而堆又分成了三大部分:新生代、老年代和永久代。永久代我们不说,因为它保存的是类的信息,一般跟gc关系不大。新生代和老年代的回收算法不同,新生代用复制算法,老年代用标记-整理算法或者标记-清除算法,在标记-清除和标记-整理算法中,标记都是首先需要做的,只有在标记之后,gc才能够知道哪些对象是需要被回收的。

        在讲标记过程之前,先讲一下几个概念:gc roots、三种颜色的意义、新生代、老年代

        会被定义为gc roots的对象有

                1、虚拟机栈中引用的对象:虚拟机栈中保存的是一个个的栈桢,每个栈桢中保存的是

        它对应的方法的局部变量、部分运行结果、方法出口等信息,局部变量所引用的对象会被

        定义为gc roots;

                2、本地方法栈中引用的对象:也就是native方法中引用的对象会被定义为gc roots;

                3、方法区中类的静态变量和常量引用的对象会被定义为gc roots。

        三种颜色的意义

                白色:未被标记的对象

                灰色:已被标记,但是还有至少一个直接引用未被标记的对象

                黑色:已被标记,并且所有直接引用均已被标记的对象

为什么要分新生代、老年代呢?

        因为堆中对象的生命周期长短不同,有的生命周期很长,比如连接对象、线程对象等;而有的对象生命周期很短。那么生命周期长的和短的对象就适合用不同的回收算法去回收,以提高垃圾回收的效率。 

        新生代:新生代中保存的是大部分的新被创建的对象【新创建的对象如果很大的话,不会保存在新生代中,会被保存到老年代中】,这些对象大部分都是朝生夕死,因此在新生代中会有大量的minor gc;新生代又划分为三个区域;Eden区、survivor from区、survivor to区,新生代用复制算法进行minor gc,在执行minor gc的时候,会将Eden区和survivor from区中存活的对象转移到survivor to区中,然后将Eden区和survivor from区清空,在这过程中要将存活的对象年龄加1,如果某个对象年龄达到了15,则将这个对象转移到老年代;在一次minor gc之后,将survivor from和survivor to两个区域的功能互换,那么下一次minor gc的时候就是将Eden区和survivor to区的存活对象转移到survivor from区了。

        老年代:老年代中保存的是年龄比较大的对象以及占用内存比较大的新创建的对象,老年代因为存储的是存活率比较高的对象,所以比较稳定,不会进行大量的major gc,但是当要保存一个比较大的新创建的对象的时候,如果没有足够大的连续内存去保存它,那么会触发major gc,以便腾出空间去保存它;新生代在执行minor gc时有可能导致年龄大的对象转移到老年代,如果这时候老年代没有足够的空间了,那么也会触发老年代执行major gc;并且新生代在执行minor gc之前,老年代会对新生代有一个存储空间担保规则,如果它无法担保有足够的内存去存储新生代可能晋升到老年代的那些对象,那么也会触发major gc。老年代用标记-整理 或者 标记-清除算法执行major gc,它会扫描老年代中所有的对象,标记出存活的对象,然后将没有标记的对象回收,当major gc之后依然没有足够的空间去保存新的对象的时候,就会抛出OOM异常。

        我们知道,java中的线程分为用户线程和守护线程,用户线程是执行具体任务的线程,守护线程是为用户线程服务的后台线程,当我们启动一个用户线程的时候,jvm会自动地启动一个进行垃圾回收的守护线程,用于回收这个用户线程执行过程中产生的垃圾,这个垃圾回收线程在开始回收对象之前,会对对象进行三色标记,三色标记的过程

        1、初始的时候,除了gc roots对象是黑色的以外,其他所有的对象都是白色的

        2、将gc roots对象直接引用的白色对象标记为灰色

        3、将灰色对象直接引用的白色对象标记为灰色,并将灰色对象本身标记为黑色

        4、如果某个灰色对象已经没有未被标记的直接引用了,那么将这个对象标记为黑色

        5、如果依然有灰色对象存在未被标记的直接引用,则重复上面的从3开始的标记步骤,直到没有灰色对象存在

        这时只剩下了黑色和白色对象,gc要回收的便是白色对象

        在垃圾回收器的实现中,无论是CMS还是G1,都有上述的三色标记过程,CMS进行垃圾回收的算法为'标记-清除',过程分为4步:初始标记 -> 并发标记 -> 重新标记 -> 并发清理;G1进行垃圾回收的算法在整体上看为'标记-整理',局部看为'复制算法',过程也分为4步:初始标记 -> 并发标记 -> 最终标记 -> 筛选回收。这两个回收器的前三步就对应着三色标记过程。

        但其实这两个收集器的第二步“并发标记”过程是会有问题的,因为执行三色标记的守护线程是和它对应的用户线程并发执行的,那么就会有并发标记的问题:如果在并发标记过程中,对象的引用关系发生了变化,那么就有可能产生多标和漏标的问题。

        多标:如果某个之前被引用的对象a又不被引用了,而引用关系改变时a对象已经被标记为黑色了,那么a对象就被多标了。多标的问题不大,顶多就是a对象在这次的gc中逃逸掉了,那么它可以在下一轮gc中被回收掉

        漏标:如果某个白色对象n由被对象a引用变为被对象b引用,并且引用关系改变的时候,a是灰色的,而b是黑色的,那么就会有问题,因为新引用它的b已经是黑色了,所以已经无法通过b来标记对象n了,那么一直到三色标记结束,n对象依然是白色,就会导致对象n被gc回收,这就导致了不该被回收的对象被回收掉了,会使程序出现严重的bug。

        解决漏标的问题,可以用写屏障+增量更新方案:

        增量更新:当某个黑色的对象black去新引用一个对象obj时,会将这个黑色对象black标记为灰色,这样obj就不会被漏标了。CMS垃圾回收器就是使用了增量更新。

        需要注意的是,即便某个对象被标记为不可达【白色】了,它也不一定真的会被回收,它还有可能通过一个方法翻盘,这个方法叫做finalize。

        用finalize翻盘:

        finalize是定义在Object类中的一个方法,它的作用是在回收对象之前做一些诸如关闭资源的操作,这个方法只可能被执行一次,因为Object类是所有类的父类,所以任何类都可以去重写这个方法。

        gc在对对象进行了第一次标记之后,还要去判断这个对象的finalize方法是否有必要执行,只有对象重写了finalize方法并且它的finalize方法还未执行过,它才有必要执行finalize方法;如果某个对象的finalize方法没有必要执行,那么它的命运就决定了,它肯定会被gc回收;如果某个对象的finalize方法有必要执行,那么这个对象会被放在一个专用队列F-Queue中,jvm会启动一个专门的低优先级的线程去执行这个队列中所有对象的finalize方法,如果一个对象在finalize方法中被重新引用了,那么它会被移出F-Queue,也就是它逃避掉了被gc清除的命运;而那些在finalize方法中未被重新引用的对象,在finalize方法执行完毕之后,会被进行第二次标记,这些对象就真的要被清除了。文章来源地址https://www.toymoban.com/news/detail-620526.html

到了这里,关于可达性分析、三色标记、新生代、老年代的关系是什么的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于高斯两步移动搜寻法(2SFCA)的城市绿地可达性分析

    【2SFCA的基本思路,可以略过】 对每个供给点j,搜索所有在j搜寻半径(d0)范围内的需求点(k),计算供需比Rj;对每个需求点i,搜索所有在i搜寻半径(d0)范围内的供给点(j),将所有的供需比Rj加总得到i点的可达性Ai。 【数据】 成都市城区绿地数据、各街道小区数据、

    2023年04月21日
    浏览(41)
  • 邻接矩阵、可达性矩阵、完全关联矩阵、可达性矩阵的计算

    邻接矩阵:很简单,就是两个点有关系就是1,没有关系就是0 可达性矩阵:非常简单,两点之间有路为1,没有路为0 可发行矩阵的计算 :有n个元素,初始可达性矩阵为A,那么最终的矩阵 B= 完全关联矩阵:描述点与边的关系,如果该点和该边有关系为1,没有关系就为0,非常

    2024年01月25日
    浏览(65)
  • 【数据库+Engine】吉大核酸采样点空间分布与可达性分析系统集采样管理一键式平台报告

    无法直接粘贴图片 报告,源程序,介绍视频下载链接如下: https://download.csdn.net/download/qq_54263076/87354460 每一张表所对应的角色的领域范围和空间如下: 第一子集.核酸总流程表:单号ID,待检员ID,取样员ID,取样时间,取样地点,核酸试剂编号ID 第二子集.人员表:人员ID,姓

    2023年04月20日
    浏览(44)
  • 新生代与老年代

    在Java虚拟机(JVM)中,内存被划分为多个不同的区域,其中包括新生代(Young Generation)和老年代(Old Generation)。 新生代是用于存储新创建的对象的区域。大多数对象在创建后很快就变得不可达(unreachable),因此新生代被设计成较小且较短暂的区域。新生代又分为两个部分

    2024年02月11日
    浏览(41)
  • JVM基础(9)——新生代调优

    作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO 联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬 学习必须往深处挖,挖的越深,基础越扎实! 阶段1、深入多线程 阶段2、深入多线程设计模式 阶段3、深入juc源码解析

    2024年01月16日
    浏览(55)
  • 华为云新生代开发者招募

    开发者您好,我们是华为2012UCD的研究团队 为了解年轻开发者的开发现状和趋势 正在邀请各位先锋开发者,与我们进行2小时的线上交流(江浙沪附近可线下交流) 聊聊您日常开发工作中的产品使用需求 成功参与访谈者将获得至少300元京东卡(取决于访谈时长和内容)作为酬

    2024年02月11日
    浏览(43)
  • 图论可达性c语言实现

           图论中的可达性是指在图中是否存在从一个顶点到另一个顶点的路径。这是图论中的一个基本概念,对于许多实际问题的建模和解决都非常重要。以下是关于图论可达性的一些重要概念和信息: 有向图和无向图: 图可以分为有向图和无向图。在有向图中,边有方向,

    2024年01月23日
    浏览(40)
  • JVM内存02-新生代和老年代介绍:

    JVM 中新生代和老年代的比例大小是可以通过参数进行调整的。 默认情况下,新生代和老年代的比例是 1:2, 也就是新生代占整个堆空间的 1/3,老年代占整个堆空间的 2/3。 可以使用 JVM 参数 -XX:NewRatio=n 来调整新生代和老年代的比例。 其中,n 表示老年代和新生代的比例, 比

    2024年02月16日
    浏览(38)
  • 探讨AI绘画:技术进步与伦理道德并存的新生代艺术?

      随着人工智能技术的不断发展,AI绘画也成为了热门领域之一。在这个领域中,Midjourney是一款受到广泛关注的AI绘图工具。但是,随着AI绘画技术的发展,也有越来越多的问题和争议浮现出来。在这里,我们将从几个角度来探讨AI绘画的发展现状以及可能带来的影响。   

    2024年02月11日
    浏览(41)
  • 【Linux】测试ip:port端口是否连通即可达性测试

    【Linux】测试ip:port端口是否连通即可达性测试 0、背景 1、telnet可达性测试 2、curl可达性测试 3、wget可达性测试 0、背景 在视觉项目开发调试的过程中经常需要判定IPC是否可达,在做服务的时候也需要判定服务器是否可达。 本博客介绍3种常用的工具(telnet、curl、wget)进行可

    2023年04月17日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包