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

文章目录

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

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收集器使用读屏障是爱你整理过程和用户线程的并发执行

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

子数组按位与为k

注意这里的子数组是连续的非空的数组&#xff0c;我们要学会与处理就是求交集 class Solution { public:long long countSubarrays(vector<int>& nums, int k) {long long ans 0;for (int i 0; i < nums.size(); i) {int x nums[i];for (int j i - 1; j > …

MATLAB 2024b 更新了些什么?

MATLAB 2024b版本已经推出了预览版&#xff0c;本期介绍一些MATLAB部分的主要的更新内容。 帮助浏览器被移除 在此前的版本&#xff0c;当我们从MATLAB中访问帮助文档时&#xff0c;默认会通过MATLAB的帮助浏览器&#xff08;Help browser&#xff09;。 2024b版本开始&…

【Linux】压缩命令——gzip,bzip2,xz

1.压缩文件的用途与技术 你是否有过文件太大&#xff0c;导致无法以正常的E-mail方式发送&#xff1f;又或学校、厂商要求使用CD或DVD来做数据归档之用&#xff0c;但是你的单一文件却都比这些传统的一次性存储媒介还要大&#xff0c;那怎么分成多块来刻录&#xff1f;还有&am…

[搭建个人网站] 云服务器 or 本地环境搭建

别人没有的&#xff0c;你有&#xff0c;你就牛。 面试&#xff0c;吹牛皮的时候 都可以拉出来溜溜 本文介绍2种搭建网站模式方式&#xff1a;区别嘛&#xff08;花钱跟不花钱&#xff09; 花钱&#xff1a; 1. 先购买个域名。。&#xff08;这里就不多介绍了&#xff0c;随便…

昇思学习打卡-9-ResNet50图像分类

文章目录 网络介绍数据可视化部分网络实现Building Block结构BottleNet模块 模型训练推理结果可视化学习总结优点不足 网络介绍 在ResNet网络提出之前&#xff0c;传统的卷积神经网络都是将一系列的卷积层和池化层堆叠得到的&#xff0c;但当网络堆叠到一定深度时&#xff0c;…

STM32崩溃问题排查

文章目录 前言1. 问题说明2. STM32&#xff08;Cortex M4内核&#xff09;的寄存器3. 崩溃问题分析3.1 崩溃信息的来源是哪里&#xff1f;3.2 崩溃信息中的每个关键字代表的含义3.3 利用崩溃信息去查找造成崩溃的点3.4 keil5中怎么根据地址找到问题点3.5 keil5上编译时怎么输出…

C++模板元编程(二)——完美转发

完美转发指的是函数模板可以将自己的参数“完美”地转发给内部调用的其它函数。所谓完美&#xff0c;即不仅能准确地转发参数的值&#xff0c;还能保证被转发参数的左、右值属性不变。 文章目录 场景旧的方法新的方法内部实现参考文献 场景 思考下面的代码&#xff1a; templ…

深度学习之网络构建

目标 选择合适的神经网络 卷积神经网络&#xff08;CNN&#xff09;&#xff1a;我们处理图片、视频一般选择CNN 循环神经网络&#xff08;RNN&#xff09;&#xff1a;我们处理时序数据一般选择RNN 超参数的设置 为什么训练的模型的错误率居高不下 如何调测出最优的超参数 …

【pytorch20】多分类问题

网络结构以及示例 该网络的输出不是一层或两层的&#xff0c;而是一个十层的代表有十分类 新建三个线性层&#xff0c;每个线性层都有w和b的tensor 首先输入维度是784&#xff0c;第一个维度是ch_out,第二个维度才是ch_in(由于后面要转置)&#xff0c;没有经过softmax函数和…

C++ 引用——引用的本质

本质&#xff1a;引用的本质在c内部实现是一个指针常量 C推荐用引用技术&#xff0c;因为语法方便&#xff0c;引用本质是指针常量&#xff0c;但是所有的指针操作编译器都帮我们做了 示例&#xff1a; 运行结果&#xff1a;

C++初学者指南-4.诊断---valgrind

C初学者指南-4.诊断—Valgrind Valgrind&#xff08;内存错误检测工具&#xff09; 检测常见运行时错误 读/写释放的内存或不正确的堆栈区域使用未初始化的值不正确的内存释放&#xff0c;如双重释放滥用内存分配函数内存泄漏–非故意的内存消耗通常与程序逻辑缺陷有关&#xf…

水箱高低水位浮球液位开关工作原理

工作原理 水箱高低水位浮球液位开关是一种利用浮球随液位升降来实现液位控制的设备。其基本原理是浮球在液体的浮力作用下上下浮动&#xff0c;通过磁性作用驱动与之相连的磁簧开关的开合&#xff0c;从而实现液位的高低控制和报警。当液位升高时&#xff0c;浮球上浮&#xf…

cmake find_package 使用笔记

目录 1 find_package2 config mode2.1 搜索的文件名2.2 搜索路径 3 module mode3.1 搜索的文件名3.2 搜索路径 参考 1 find_package 这是官方文档 下面是学习总结&#xff1a; 首先是find_package的作用是什么&#xff1f;引入预编译的库。 find_package有两种模式&#xff1a…

C语言 指针和数组——指针和二维数组之间的关系

目录 换个角度看二维数组 指向二维数组的行指针 按行指针访问二维数组元素 再换一个角度看二维数组 按列指针访问二维数组元素 二维数组作函数参数 指向二维数组的行指针作函数参数 指向二维数组的列指针作函数参数​编辑 用const保护你传给函数的数据 小结 换个角度看…

使用antd的<Form/>组件获取富文本编辑器输入的数据

前端开发中&#xff0c;嵌入富文本编辑器时&#xff0c;可以通过富文本编辑器自身的事件处理函数将数据传输给后端。有时候&#xff0c;场景稍微复杂点&#xff0c;比如一个输入页面除了要保存富文本编辑器的内容到后端&#xff0c;可能还有一些其他输入组件获取到的数据也一并…

Win10安装MongoDB(详细版)

文章目录 1、安装MongoDB Server1.1. 下载1.2. 安装 2、手动安装MongoDB Compass(GUI可视工具)2.1. 下载2.2.安装 3、测试连接3.1.MongoDB Compass 连接3.2.使用Navicat连接 1、安装MongoDB Server 1.1. 下载 官网下载地址 https://www.mongodb.com/try/download/community …

『大模型笔记』《Pytorch实用教程》(第二版)

『大模型笔记』《Pytorch实用教程》(第二版) 文章目录 一. 《Pytorch实用教程》(第二版)1.1 上篇1.2 中篇1.3 下篇1.4 本书亮点1.5 本书内容及结构二. 参考文献🖥️ 配套代码(开源免费):https://github.com/TingsongYu/PyTorch-Tutorial-2nd📚 在线阅读(开源免费)…

nginx相关概念(反向代理、负载均衡)

1 Nginx 是什么 Nginx是一款轻量级的Web 服务器&#xff0c;其特点是占有内存少&#xff0c;并发能力强 2 Nginx 反向代理 正向代理代替客户端去发送请求反向代理代替服务端接受请求 2.1 正向代理 若客户端无法直接访问到目标服务器 server 则客户端需要配置代理服务器 pr…

正则表达式 先行断言 \S {} 示例

目录 数据准备一. 先行断言1.1 正向先行断言1.2 负向先行断言 二. 配合 {} 和 \S 使用2.1 匹配一个任意非空白字符2.2 匹配任意多个非空白字符2.3 匹配3个非空白字符2.4 匹配至少3个非空白字符2.5 匹配0~3个非空白字符 数据准备 ⏹文件1 0561-10 AAA 123 dfg 345 sss 0561-2…

【电路笔记】-AB类放大器

AB类放大器 文章目录 AB类放大器1、概述2、AB类放大器介绍3、AB类放大器效率4、偏置方法4.1 电压偏置4.2 分压网络4.3 电位器偏置4.4 二极管偏置5、二极管网络和电流源6、AB类放大器的电源分配7、总结1、概述 A类放大器提供非常好的输出线性度,这意味着可以忠实地再现信号,但…