【Java】垃圾回收学习笔记(二):分代假说与垃圾回收算法

文章目录

  • 0. 分代收集理论
    • 分代假说
    • 分代GC定义
  • 1. 垃圾回收算法
    • 1.1 标记清除(Mark-Sweep)算法
      • 优点
      • 缺点
    • 1.2 标记复制算法
      • 优点
      • 缺点
      • 为什么是8:1:1?
    • 1.3 标记整理算法
      • 优点
      • 缺点
  • 2. 是否移动?
  • Reference

0. 分代收集理论

分代假说

现在多数JVM GC都遵循分代收集(Generational Collection)理论,其中涉及三个经验性的分代假说:

  1. 弱分代假说(Weak Generational Hypothesis):绝大多说对象都是朝生夕灭
    1. 对象创建先进入新生代(Young/Nursery),进行较为频繁、局限于新生代的Minor GC
  2. 强分代假说(Strong Generational Hypothesis):熬过越多次垃圾收集过程的对象,越难以消亡
    1. 对象经过几轮gc后进入老年代(Old/Tenured),进行次数相对少、局限于老年代的Major GC
  3. 跨代引用假说(Intergenerational Reference Hypothesis):跨代引用相对于同代引用来说占比极少
    1. 跨代引用:比如新生代对象可能被老年代所引用,所以Minor GC时需要在固定的GC Roots外,再额外增加老年代中的Roots来保证可达性分析的正确性(young引用old同理)。
    2. 以新生代被老年代引用为例,根据跨代引用假说,如果遍历整个老年代的引用关系来增加GC Roots,效率将会非常低,可以通过在新生代增加专门的数据结构(记忆集,Rememered),来标识跨代引用关系。比如,CMS和G1垃圾收集器都会通过写前屏障的方式,将跨代引用记录在卡表(可以看做一种记忆集)中。

分代GC定义

前面有提到Minor GC、Major GC之类的说法,其实就是不同分代中的GC行为,类似的定义包括:

  • 部分收集(Partial GC): 不完整收集整个Java堆的GC。又分为:
    • 新生代收集(Minor GC/Young GC):目标是新生代的GC
    • 老年代收集(Major GC/Old GC):目标是老年代的GC。目前只有CMS收集器会有只针对老年代的GC。
    • 混合收集(Mixed GC):目标是整个新生代部分老年代的GC。目前只有G1收集器会有Mixed GC。
  • 整堆收集(Full GC):整个Java堆和方法区的GC。

1. 垃圾回收算法

1.1 标记清除(Mark-Sweep)算法

将垃圾回收分为标记和清除两个阶段:

  1. 标记阶段:标记出所有活跃对象(或者标记死亡对象)
  2. 清除阶段:回收未被标记为活跃的对象(或者标记死亡的对象)

在这里插入图片描述

优点

实现简单、速度快。后面的收集算法大多在此基础上改进得来的。

缺点

  • 执行效率不稳定:标记、清除的执行效率随对象数增加而降低;
  • 清除后可能造成内存碎片:如果new了一个大的对象,碎片化的内存没法使用,造成内存浪费。

1.2 标记复制算法

将内存分为两个区域:一个区域用于存储存活对象,一个保留区域

  1. 标记处所有存活对象,移动到保留区域
  2. 移动到保留区域的对象进行内存整理(避免碎片化)
  3. 将原有区域整个清理掉,变成新的保留区域

在这里插入图片描述

现代的商用Java虚拟机大多采用改进的标记复制算法来进行新生代GC。

优点

效率很高,不会产生内存碎片

缺点

  • 对象存活率较高时,需要很多复制操作,效率降低。比如老年代中,大部分对象存活周期都很长(前面提到过的强分代假说),所以老年代中一般不采用标记-复制算法。
  • 保留区域与存活区域1:1(半区复制,Semispace Copying)的话,会有一半内存被浪费。

一些现代的垃圾收集器(ParNew等)中将新生代分为Eden区+2个Survive(Survivor)区(8:1:1,Appel式回收)解决内存浪费:new对象先分配到Eden中,将Eden与非保留区域的survivor1标记后,将存活对象移动到作为保留区域的Survivor2中,将其他区域(Eden与Survivor1)GC,survivor1成为新的保留区域。

为什么是8:1:1?

大家都知道新生代对象的寿命大部分都很短,也就是弱分代假说中的“朝生夕灭”。IBM公司有研究对对象的“朝生夕灭”做了量化,即新生代对象中98%熬不过第一轮GC。因此完全没必要按照1:1分配新生代空间。

HotSpot虚拟机默认的Eden与Survivor比例是8:1,可以保证每次新生代可用内存空间为整个新生代的90%(Eden 80%+非保留区域survivor的10%)。

但可能存在多于10%对象存活的情况。因此,当一次Minor GC后,Survivor空间不足以容纳幸存的对象,就需要老年代作为保底。

1.3 标记整理算法

  • 标记阶段:标记存活对象,清除垃圾对象。
  • 整理阶段:内存整理,让存活对象向内存空间的一端移动。

在这里插入图片描述

优点

  • 相比于标记-复制算法,内存使用效率高,吞吐量高;
  • 同时也不会有标记-清除算法的内存碎片化问题。

这里吞吐量的定义为:运行用户代码时间/(运行用户代码时间+运行垃圾收集时间)

缺点

  • 消耗时间比较长,高并发场景可能影响系统性能

大家应该多少都听说过“Stop The World ”,也就是移动存活对象时(特别是老年代每次回收都有大量对象存活,需要大量移动操作),移动操作必须暂停用户应用程序。因此有时候老年代空间不足或内存碎片化过于严重(大对象内存申请不了),导致Full GC,就会面临STW的困境。如果想要减少STW的次数,可以适当增加新生代的比例,即大部分对象生命周期在新生代快速流转,可以适当减少老年代的STW。

标记-清除算法也要停顿用户线程,但是时间相对较短

2. 是否移动?

标记-清除算法跟其他两个算法最本质的区别,在于它没有移动操作,也因此存在内存碎片化的问题。当然,即使不移动,内存碎片化也不是没有解决办法,只能依赖更复杂的内存分配器和内存访问器来解决。但是内存访问是用户程序最频繁的操作之一,如果增加额外负担,会影响吞吐量。

可见:

  • 移动对象:内存回收会更加复杂,GC停顿时间较长,但吞吐量会更划算;
  • 不移动对象:内存分配时会更加复杂,GC停顿时间更短,但内存分配的额外操作会极大影响吞吐量。

因此,HotSpot虚拟机中,关注吞吐量的Parallel Scavenge收集器给予标记-整理算法,关注延迟的CMS(老年代)基于标记-清除算法(实际上CMS都会用,大多数时间标记-删除,等碎片化道影响大对象分配时,标记-整理一次)。

最新的ZGC和Shenandoah收集器使用读屏障是爱你整理过程和用户线程的并发执行

Reference

《深入理解java虚拟机:JVM高级特性与最佳时间(第3版)》 周志明

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

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

相关文章

Navicat和MySQL的安装

1、下载 Navicat Navicat 官网:www.navicat.com.cn/ 在产品中可以看到很多的产品,点击免费试用 Navicat Premium 即可,是一套多连数据库开发工具,其他的只能连接单一类型数据库 点击试用 选择系统直接下载 二、安装 Navicat 安…

element el-table实现表格动态增加/删除/编辑表格行,带校验规则

本篇文章记录el-table增加一行可编辑的数据列,进行增删改。 1.增加空白行 直接在页面mounted时对form里面的table列表增加一行数据,直接使用push() 方法增加一列数据这个时候也可以设置一些默认值。比如案例里面的 产品件数 。 mounted() {this.$nextTi…

linux创建定时任务

crontab方式 先查看是否有cron systemctl status crond 没有的话就安装 yum install cronie 打开你的crontab文件进行编辑。使用以下命令打开当前用户的crontab文件: crontab -e * * * * * /export/test.sh >> /export/test.log 2>&1/export/test.s…

差分算法中的F 和CR参数

自查使用。。F 类似梯度的大小 两者都用于种群中新个体的生成

leetcode--从中序与后序遍历序列构造二叉树

leeocode地址:从中序与后序遍历序列构造二叉树 给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。 示例 1: 输入:inorder …

Unity插件 Unitask学习日志

Unity插件 Unitask学习日志 下载地址 https://github.com/Cysharp/UniTask点击这里可以查阅中文文档 在Unity 2020,2021 中使用UPM下载会找不到,可以使用2022版本的unity可以在upm中找到。 安装方式: 下载zip之后解压, 复制Plugins 到Uni…

01. 数组篇(进行中......)

一. 前缀和技巧 &#xff08;1&#xff09;前缀和 前缀和技巧适用于快速、频繁地计算一个索引区间内的元素之和。 class NumArray { public:vector<int> preSum; //前缀和数组NumArray(vector<int>& nums) {//preSum[0] 0&#xff0c;便于计算累加和preSum…

Spring中的工厂模式详解及应用示例

1. Spring中的BeanFactory BeanFactory是一个接口&#xff0c;表示它是一个工厂&#xff0c;负责生产和管理bean。在Spring中&#xff0c;BeanFactory是IOC容器的核心接口&#xff0c;定义了管理Bean的通用方法&#xff0c;如 getBean 和 containsBean。 BeanFactory与IOC容器…

Python编程:如何有效等待套接字的读取与关闭

背景介绍 网络编程是现代应用程序开发的重要组成部分&#xff0c;尤其是在大数据和实时通信的背景下。套接字&#xff08;Socket&#xff09;作为网络通信的核心技术&#xff0c;是开发网络应用程序的基础。在Python编程中&#xff0c;如何有效地等待套接字的读取与关闭事件是…

柔性测斜仪:监测钻孔位移的核心利器

柔性测斜仪&#xff0c;作为一款创新的测量工具&#xff0c;凭借其卓越的设计与性能&#xff0c;在地下建筑、桥梁、隧道及水利水电工程等领域展现出非凡的应用价值。其安装便捷、操作简便、高精度及长寿命等特性&#xff0c;使之成为监测钻孔垂直与水平位移的理想选择。以下是…

【ComfyUI的API接口调用示例】

ComfyUI的API接口调用示例 本文目的 本文调用接口示例主要指导需要调用ComfyUI的开发者如何调用ComfyUI官方的API接口提交任务、查询历史、获取绘画视频结果等。 阅读本文的前提是你本地已经安装了ComfyUI&#xff0c;并且对工作流绘画和生成视频已经有所了解。注意如图右边栏…

arm架构安装chrome

在ARM架构设备上安装谷歌软件或应用通常涉及到几个步骤&#xff0c;这取决于你要安装的具体谷歌产品&#xff0c;比如谷歌浏览器、Google Play服务或者是其他谷歌开发的软件。下面我会给出一些常见的指导步骤&#xff0c;以安装谷歌浏览器为例&#xff1a; 在Linux ARM64上安装…

零基础做项目---五子棋对战---day02

用户模块 完成注册登录&#xff0c;以及用户分数管理~使用数据库来保存上述用户信息. 使用 MyBatis来连接并操作数据库了 主要步骤: 1.修改 Spring的配置文件,使数据库可以被连接上. 2.创建实体类&#xff0c;用户, User 3.创建Mapper接口~ 4.实现MyBatis 的相关xml配置…

MySQL安全值守常用语句

一、用户权限设置 1、Mysql中用户是如何定义的 用户名主机域 10.0.0.5110.0.0.%%10.0.0.0/255.255.255.0Db01Localhost127.0.0.1 2、用户创建 create user xinjing% identified by 123 3、用户删除 drop user username&#xff1b;username 是要删除的用户名:如 drop user root…

GDidees CMS v3.9.1 本地文件泄露漏洞(CVE-2023-27179)

前言 CVE-2023-27179 是一个影响 GDidees CMS v3.9.1 及更低版本的任意文件下载漏洞。这个漏洞存在于 /_admin/imgdownload.php 文件中&#xff0c;攻击者可以通过向 filename 参数传递恶意输入来下载服务器上的任意文件。 漏洞的根源在于对用户输入的 filename 参数处理不当…

【C++修行之道】string类练习题

目录 387. 字符串中的第一个唯一字符 125. 验证回文串 917. 仅仅反转字母 415. 字符串相加&#xff08;重点&#xff09; 541. 反转字符串 II 387. 字符串中的第一个唯一字符 字符串中的第一个唯一字符 - 力扣&#xff08;LeetCode&#xff09; 给定一个字符串 s &#…

中霖教育怎么样?税务专业可以考哪些证书?

在税务专业领域&#xff0c;专业技能的认证对职业发展至关重要。以下为税务专业相关可以考的证书&#xff1a; 1. 注册税务师资格证书&#xff1a;该证书是税务专业人士的关键资质&#xff0c;使持证者可以从事税务相关工作。 2. 会计职称证书&#xff1a;会计系列证书分为初…

笔记本系统

笔记本更新升级 笔记本购入太早&#xff0c;所用内存只有4G&#xff0c;通过更好内存条升级系统性能 查看电脑支持内存大小 cmd命令输入wmic memphysical get maxcapacity 这串数字就是电脑最大支持内存数值&#xff0c;做除法除两次1024&#xff01;&#xff0c;得出来的…

查看oracle ojdbc所支持的JDBC驱动版本

oracle jcbc驱动的下载地址参考&#xff1a;JDBC and UCP Downloads page 其实上文中对ojdbc所支持的JDBC驱动版本已经有说明了&#xff0c;不过&#xff0c;因为oracle的驱动包很多时间&#xff0c;都是在公司内部私服里上传维护的&#xff0c;上传的时候&#xff0c;可能又没…

flutter 实现AppStore左右滑动

在AppStore中如何实现左右滑动&#xff0c;因为使用PageView会居中显示&#xff0c;不会居左显示&#xff0c;目前没有找到解决方案&#xff0c;我使用的方案是ListView自定义physics实现的。 代码 SizedBox(width: 200,height: 400,child: ListView.builder(scrollDirection:…