JVM 调优 2:GC 如何判断对象是否为垃圾,三色标记算法应用原理及存在的问题?

文章目录

  • 前言
  • 一、如何判断一个对象是否为垃圾?
    • 1.1、reference count(引用计数)
    • 1.2、reference count(引用计数)存在的问题
  • 二、Root Searching(根可达算法或根搜索算法)
    • 2.1、Root Searching 释义
    • 2.2、根对象(root)的类型
  • 三、三色标记算法原理与存在的问题
    • 3.1、Mark-Sweep(标记清除)
      • 3.1.1、Mark-Sweep(标记清除)应用原理
      • 3.1.2、存在问题-内存碎片化
    • 3.2、Copying(拷贝)
      • 3.2.1、Copying(拷贝)应用原理
      • 3.2.2、存在问题-浪费空间
    • 3.3、Mark-Compact(标记压缩或标记整理)
      • 3.3.1、Mark-Compact(标记压缩或标记整理)应用原理
      • 3.3.2、存在的问题-效率过低
  • 四、垃圾回收器的制定原则
    • 4.1、综合三种算法的 GC
    • 4.2、新生代里面对象的 age 要取值多少?
    • 4.3、堆内存逻辑分区介绍(适用分代垃圾回收器)
    • 4.4、为什么年轻代用 Copying(拷贝)算法?
    • 4.5、 Copying(拷贝)算法在年轻代中的具体应用
  • 总结


前言

本文进入我们进入 JVM 调优系列 2,GC 如何判断对象是否为垃圾,这个是面试中的高频面试题,同时对于 GC 的三色标记算法属于 GC 算法的核心内容,我们将通过算法的应用原理进行深度剖析并分析存在的问题,由此来得出 GC 的制定机制是什么?这里就不再强调重点了,因为到处都是重点!

在这里插入图片描述


一、如何判断一个对象是否为垃圾?

1.1、reference count(引用计数)

查看是否有引用指向该对象,有则说明该对象不是垃圾,反之就是垃圾。

我们通过下图的引用对象案例来说明。

在这里插入图片描述
如上图所示,我们可以看到一共是存在四个阶段。

  • 第一阶段,有 3 个引用指向该对象,那该对象肯定不是垃圾。
  • 第二三阶段,部分引用消失,分别各有 2 个和 3 个引用指向该对象,那该对象仍然不是垃圾。
  • 第四阶段,没有任何引用再指向该对象,该对象沦为垃圾。这时垃圾回收器就可以将其回收。

1.2、reference count(引用计数)存在的问题

当出现循环引用时,如下图所示:

在这里插入图片描述
我们可以看到,三个对象各自指向循环中的另一个对象,但是没有其他引用指向这三个对象,那这三个对象就属于“一堆垃圾”。

那现在我们上面所说的引用计数就不能解决这个该问题,这时我们就需要使用另外一种定位方式——Root Searching(根可达算法或根搜索算法)

二、Root Searching(根可达算法或根搜索算法)

2.1、Root Searching 释义

所谓的“根”即是:所有的程序都是从 main 方法来运行,在 main 方法里面 new 出来的对象即为根对象。

例如:在 main 方法里面我们 new 了一个 list 集合,在 list 集合中我们又可以存放若干其他对象,那我们就称 list 为根对象,我们顺着根的数据结构往下走,只要存在引用指向的对象,那该对象就不是垃圾,反之不存在引用的对象,那该对象就是垃圾。

在这里插入图片描述
如上图所示,对象一、二、三、四、五均是存在根对象的引用,对象五、六之间是我们上面所提到的循环引用,对象八不存在引用,故对象六、七、八是垃圾。

2.2、根对象(root)的类型

根对象不仅仅包括我们上面所说的 main 方法里面的对象,属于根对象的还有以下这些:

  • JVM stack
  • native method stack
  • runtime constant pool
  • static references in method area
  • Clazz

三、三色标记算法原理与存在的问题

GC Algorithms 到目前为止一共是有三种,我们将一一进行介绍。

  • Mark-Sweep(标记清除)
  • Copying(拷贝)
  • Mark-Compact(标记压缩或标记整理)

3.1、Mark-Sweep(标记清除)

3.1.1、Mark-Sweep(标记清除)应用原理

在这里插入图片描述
如上图所示,我们将可回收的垃圾对象进行标记定位,进行清除即可。将垃圾位变为可用位

3.1.2、存在问题-内存碎片化

算法比较简单,存在缺点,长时间的运行,内存中会存在大量的碎片(碎片化问题)。

何为碎片化?

由上述得知,每一小块可回收内存均需要标记后单独清除,在业务量较大,频繁更新数据的情况下,会有个别的“碎片”长期存在于内存中不去使用,占用资源空间。大量的碎片就会造成查询效率极其低下,所以我们就需要进行处理。

3.2、Copying(拷贝)

如果我们不想出现碎片化问题,我们就可以考虑使用 Copying(拷贝)算法。

3.2.1、Copying(拷贝)应用原理

在这里插入图片描述
如上图所示,拷贝算法不管内存有多大,直接一分为二,每次使用仅使用内存的一半,在被使用的内存即将用尽时,将可以使用的存活对象拷贝到另一半内存中,将剩下的可回收的垃圾对象进行回收操作。在另一半内存中进行正常操作,如此循环往复

这种算法每次拷贝完成所有的内存空间都是排列在一起,故不会产生碎片化问题。

3.2.2、存在问题-浪费空间

该算法的优势即是它的劣势,每次仅可以使用一般的内存空间进行操作,相当于浪费了一半的内存空间。

3.3、Mark-Compact(标记压缩或标记整理)

Mark-Compact(标记压缩)的优势在于完善了上述两种算法存在的缺点,既不存在碎片化问题,也不浪费空间。

3.3.1、Mark-Compact(标记压缩或标记整理)应用原理

在这里插入图片描述
把有用的存活对象压缩到内存空间的最前面,对可回收的垃圾对象进行处理,如上图所示。

3.3.2、存在的问题-效率过低

由于每次在压缩之间都需要计算空间,导致回收的效率大大降低。

四、垃圾回收器的制定原则

上述三种标记算法可谓是各有利弊,因此在实际应用中,一个垃圾回收器的制定是综合了上述三种算法。

4.1、综合三种算法的 GC

在这里插入图片描述
如上图所示,我们将新诞生的对象存放在新生代里。如果新诞生的对象经历了数次垃圾回收仍然没有被回收掉(即每经历一次垃圾回收,该对象年龄 +1,即 age++),当 age 到达一定数值,将该对象置于老年代中进行特殊处理。

4.2、新生代里面对象的 age 要取值多少?

这个即是我们进行 JVM 调优所需要的自行调整的,根据项目需求来设置
同时对于年龄的设置,与具体所使用的 GC 息息相关

  • 如果之前没有对 GC 进行调整或调优的话,默认使用的 GC 为使用的是 PS+PO(Parallel Scavenge+Parallel
    Old),默认年龄为 15。
  • 如果进行调整之后所使用的 GC 是 CMS,那 age 就是 6。
  • 如果使用的 GC 是 G1 的话,则就彻底与 age 无关,因为该 GC 不分代。

4.3、堆内存逻辑分区介绍(适用分代垃圾回收器)

在 4.1 图中,老年代为 tenured。我们将新生代分为三个部分:伊甸园区和两个 survivor 区。

  • 伊甸园区,即对象诞生的地方,存放所有新生的对象,与在西方中我们人类诞生的地方——伊甸园想对应。
  • survivor 区,幸存者区,存放没有在垃圾回收中被回收的对象,有两个,通常命名为 s0、s1 或者 s1、s2 等叫法。

我们一般在年轻代中使用的 GC 算法为 Copying(拷贝),老年代中使用的 GC 算法为 Mark-Sweep(标记清除)和 Mark-Compact(标记压缩或标记整理)。

4.4、为什么年轻代用 Copying(拷贝)算法?

首先我们先考虑 Mark-Sweep(标记清除)和 Mark-Compact(标记压缩或标记整理),上面我们已经说到,这两种 GC 算法的缺点分别是:产生碎片化问题、内存回收效率低

程序产生对象后,该对象很可能会在很短的时间内被回收,根据统计,一次垃圾回收可以回收掉 90% 的对象。在这样的情况下,使用 Mark-Sweep(标记清除)和 Mark-Compact(标记压缩或标记整理)效率就太低了,会造成伊甸园区很快爆满或者大规模碎片化,而新产生的对象产生放进去的效率就会大大降低。

所以在 JVM 设计中,要求年轻代的算法效率是特别高、特别快的。而 Copying(拷贝)算法的效率是最高的,但是浪费了年轻代中至少一半的内存空间。

那我们既要利用好 Copying(拷贝)算法效率高的优势,又要尽量避免内存浪费的问题,怎么解决?

4.5、 Copying(拷贝)算法在年轻代中的具体应用

第一次垃圾回收:首先将 10% 的幸存对象拷贝到第一个 survivor 中,即 s0 中,然后将整个伊甸园区进行清除。这时所有有用对象都存放在 s0 中。如下图所示:

在这里插入图片描述
第二次垃圾回收:将伊甸园区中有用的对象拷贝到另一个 survivor 中,即 s1 中,再将之前 s0 中的对象(前提是有用)拷贝到 s1 中,对伊甸园区与第一个 s0 进行垃圾回收。这时所有有用的对象存放在 s1 中。如下图所示:

在这里插入图片描述
第三次垃圾回收:再次利用 s0,将之前存活的对象与伊甸园区中产生的新对象存放在 s0 中,对伊甸园区与 s1 进行二垃圾回收。如下图所示:

在这里插入图片描述
第 n 次垃圾回收:如此循环往复利用新生代中的伊甸园区与 survivor 区即可。


总结

在本文中我们通过引用计数和根可达两种算法来判断一个对象是否为垃圾,引出在 GC 中的核心——三色标记算法,对于三色标记算法的核心和流程进行了深度剖析,以及其所存在的问题。三色标记算法又为我们引出 GC 的制定原则,GC 对于拷贝算法如何在新生代中运用以提高 JVM 的效率,都是重点内容,这里就不过分强调了。

在这里插入图片描述


我是白鹿,一个不懈奋斗的程序猿。望本文能对你有所裨益,欢迎大家的一键三连!若有其他问题、建议或者补充可以留言在文章下方,感谢大家的支持!

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

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

相关文章

班尼机器人怎么拆_博鼎建筑科技外墙错台打磨机器人和外墙螺杆洞封堵机器人—自升造楼平台1+N执行器...

继上期的混凝土整平机和智能喷淋养护系统,本期给大家介绍的是实际应用在自升造楼平台外墙环轨车上的外墙错台打磨机器人和外墙螺杆洞封堵机器人。外墙错台打磨机器人传统外墙错台处理,需要人工拿凿具对外墙面错台进行凿平处理。凿具重、操作人工容易疲劳…

架构师基础必备:“腹有诗书气自华”,驰骋一线大厂不是梦,抓紧收藏

文章目录前言一、软件1.1、何为软件?1.2、计算机软件的分类1.2.1、系统软件1.2.2、应用软件1.3、软件系统体系结构1.3.1、C/S 结构(桌面应用程序)1.3.2、B/S 结构(Web 应用程序)1.3.3、Web 服务器与数据库服务器1.3.4、…

JDK 7-JDK 21:Oracle Java SE 支持路线图/Oracle Java SE Support Roadmap 持续更新

文章目录前言一、Oracle Java SE 产品版本二、Java SE 8 的公共更新结束三、参考文档总结前言 几十年来,Java 生态系统已经成功地经历了这个过程,经历了十次主要的平台修订。长期强大的向后兼容性保护了整个生态系统的投资。同时,随着时间的推…

multisim中轻触开关在哪_现货供应轻触开关|品质确保|厂家直销

轻触开关是现今社会生活当中不可或缺的电子元器件之一,那么大家在使用的过程当中是否注意到一些细节问题。首先,我们要注意产品的放置要尽量避免接触腐蚀性气体以及过于潮湿的环境,这样很容易造成产品的损坏,减少轻触开关的使用寿…

DDoS 攻击与防护(一):如何识别 DDoS 攻击?DDoS 防护 ADS 服务有哪些?

文章目录前言一、什么是 DDoS 防护 ADS?1.1、什么是 DDoS 攻击?1.2、如何识别 DDoS 攻击?1.3、从 Web 访问流程分析 DDoS 攻击1.4、DDoS 攻击类型二、DDoS 防护 ADS 介绍2.1、Anti-DDoS 流量清洗2.2、DDoS 原生高级防护2.3、DDoS 高防三、DDo…

收藏功能_六款多功能榻榻米,装完你家会大一半!超实用,收藏

原标题:六款多功能榻榻米,装完你家会大一半!超实用,收藏当今社会城市的生活压力大,在外日夜打拼,回到家中只想做一个慵懒派,随性舒适的榻榻米,功能样式丰富,能让你彻底释…

混凝土墙开洞_新乐专业混凝土切割报价适中

新乐专业混凝土切割报价适中粘碳纤维加固,屋顶加层。本公司采用目前的钢筋混凝土切割结构分离和水钻排孔技术。真正实现对不同规格和形状的桥梁、道路、烟囱、建筑立柱、钢筋砼墙体、砖混结构墙体、建筑大梁等建筑物、构筑物实施无损切割(传统的建筑改造或局部拆除分…

class触发后让另一个class加样式_Bootstrap的按钮组样式

将一系列的.btn包裹在.btn-group内&#xff0c;并使用我们提供的插件&#xff0c;可以实现选择按钮、选取块状区的行为功能。<div class"row mt-5 d-block"><div class"btn-group"><button class"btn btn-primary">Left</b…

bsp模型适用于图计算_【论文解读】目标检测之RFBnet模型

原创声明&#xff1a;本文为 SIGAI 原创文章&#xff0c;仅供个人学习使用&#xff0c;未经允许&#xff0c;不能用于商业目的。其它机器学习、深度学习算法的全面系统讲解可以阅读《机器学习-原理、算法与应用》&#xff0c;清华大学出版社&#xff0c;雷明著&#xff0c;由SI…

win10雷电3接口驱动_“雷电3”接口知识大科普

近年来部分高端笔记本电脑在接口上会采用一种叫“雷电3”的新接口。今天小编就为大家解读一下“雷电3”接口的特性。最早的雷电接口雷电接口是由Intel开发定制的、接口类型为mini DP&#xff0c;在雷电3接口出来之前&#xff0c;雷电1和雷电2都是作为在苹果MAC上使用的&#xf…

springboot怎么返回404_深度分析:SpringBoot异常捕获与封装处理,看完你学会了吗?...

简介日常开发过程中&#xff0c;难免有的程序会因为某些原因抛出异常&#xff0c;而这些异常一般都是利用try &#xff0c;catch的方式处理异常或者throw&#xff0c;throws的方式抛出异常不管。这种方法对于程序员来说处理也比较麻烦&#xff0c;对客户来说也不太友好&#xf…

新生成长记;关于zzulioj1056,幸运数字

刚刚接触代码的我&#xff0c;对计算机愈来愈好奇&#xff0c;开学的两个月&#xff0c;几乎没看书只顾着做题&#xff0c;当然&#xff0c;不会就百度&#xff0c;或者看大佬的博客&#xff0c;这些都是好东西&#xff0c;实在看不懂的&#xff0c;就拿着跑去问学长&#xff0…

获取form表单_【第1535期】前端 Form 的表单的一个通用解决方案

前言今日早读文章由阿里布达投稿分享。布达&#xff0c;Alibaba Fusion项目组的。花名潕量。主要专注在设计系统、组件、可视化搭建这个领域正文从这开始&#xff5e;&#xff5e;Fusion Next - Form 表单解决方案前端的Form 表单主要用于解决数据获取、数据校验、数据赋值 这三…

react取消捕获_React学习笔记(三)

React学习笔记&#xff08;三&#xff09;&#xff0c;组件的生命周期React中组件也有生命周期&#xff0c;也就是说也有很多钩子函数供我们使用, 组件的生命周期&#xff0c;我们会分为四个阶段&#xff0c;初始化、运行中、销毁、错误处理(16.3之后)初始化在组件初始化阶段会…

快捷键_AutoCAD 2021中的默认快捷键、新建或编辑快捷键

文&#xff1a;CAD钟日铭。欢迎关注和点赞支持。在使用AutoCAD进行制图的过程中&#xff0c;掌握一些快捷键会提高操作效率。所谓的快捷键是指用于启动命令的键组合。例如&#xff0c;按CtrlN组合键(快捷键)新建图形文件&#xff0c;按 CtrlO组合键可打开图形文件&#xff0c;按…

出现画面抖动_连续抖动20小时!虎门大桥桥面如波浪翻滚,专家:个人感觉没问题...

前两天(5月5日)&#xff0c;虎门大桥桥面出现如波浪翻滚的起伏&#xff0c;引发广泛的关注&#xff1a;次日&#xff0c;广东交通集团通报&#xff0c;虎门大桥震动是涡振现象&#xff0c;悬索桥结构安全。专家初步判断此次涡振和桥上设置水马有关。但直到6日早上11时&#xff…

安全模式 提权_记一次渗透挖洞提权实战

摘要&#xff1a;这是一次挖掘cms通用漏洞时发现的网站&#xff0c;技术含量虽然不是很高&#xff0c;但是也拿出来和大家分享一下吧&#xff0c;希望能给一部分人带来收获。0x01 进入后台在通过googlehack语法挖掘beescms时发现了这个站点利用网上的payload&#xff0c;在/mx_…

win7无法连接打印机拒绝访问_“Windows无法连接打印机,操作失败,错误为0x000003e3”...

请求大家帮助&#xff0c;昨天在共享打印机时出现“Windows无法连接打印机&#xff0c;操作失败&#xff0c;错误为0x000003e3”。在百度百科查询的资料修改了都不行(在不重装系统前提下&#xff0c;联想台式机都是win732位系统)&#xff0c;给大家一一列举&#xff0c;请求广大…

类型全部为string_python小讲堂丨学了这么久的,这6种基本数据类型你真的理解了吗...

哈喽&#xff0c;大家好&#xff0c;欢迎来到python小讲堂&#xff0c;间歇性的努力&#xff0c;会导致持续性的一事无成&#xff0c;即使今天是除夕&#xff0c;我们也不能懈怠啊&#xff0c;今天我给大家带来的是关于python的6种基本数据类型的深入讲解&#xff0c;话不多说让…

防抖 节流_【前端面试】节流与防抖

我们用两张图表示什么是节流和防抖。防抖节流由图可见&#xff0c;防抖的意思是&#xff0c;当用户在一段时间内连续频繁的试图执行一个函数的时候&#xff0c;只有最后一次&#xff0c;函数被真正的执行。节流的意思是&#xff0c;当用户在某一个时刻执行了一次函数的时候&…