JVM系列(八) JVM 垃圾收集算法

news2025/1/24 18:02:08

前面我们了解了很多JVM配置垃圾回收的方式,但是具体垃圾是如何被回收的,或者说垃圾回收算法有哪些?今天我们文章主要讲解一下垃圾回收算法

1.分代收集理论

我们都知道 很早的JVM会把堆分为几个区域,新生代,老年代,永久代等区域,为什么要这么划分?就是为了区分对象的区域,从而根据区域去进行划分,为了分代收集

分代收集指

  • 垃圾收集器应该将Java堆划分 出不同的区域
  • 需要回收的对象依据其年龄(年龄即对象熬过垃圾收集过程的次数)分配到不同的区域之中存储。
  • 一般至少将把Java堆划分为新生代 (Young Generation)和老年代(Old Generation)两个区域
  • 在新生代中,每次垃圾收集 时都发现有大批对象死去,而每次回收后存活的少量对象
  • 少量存活的对象将会逐步晋升到老年代中存放。

在此,对于分代收集理论存在两个分代假说:

  • 绝大部分对象是熬不过第一次垃圾回收的
  • 熬过多次垃圾回收的对象是难以被标记为垃圾的。

将堆划分为不同的区域后,垃圾回收器可以只回收其中一部分区域,针对每一部分区域也可以采用不同的算法来进行回收垃圾。

一般来说堆中至少会被划分为“新生代”和“老年代”两个区域。新生代存储第一种假说类型的对象,老年代存放第二种假说类型的对象。

注意:这种设计看起来是完美的,但是如果老年代中的对象引用了新生代中的对象这个时候年轻代发生垃圾回收时,除了需要遍历GC Roots外,还需要遍历整个老年代才会确保年轻代中的对象真正没有对象引用。显然这种遍历整个老年代效率肯定会很低

因此我们先介绍第一种垃圾收集算法

2.标记-清除算法

最早出现的垃圾回收算法,之后出现的算法都是根据该算法的缺点来进行演进的。

标记-清除算法 看名字就可以知道,分为两个阶段

  • 标记阶段
    • 标记需要回收的对象完成后进行统一回收所有被标记的对象
    • 也可以标记存活的对象统一回收没有被标记的对象。
  • 清除阶段
    • 进行统一回收掉标记的对象
      就像图片中呈现的,标记出来 存活的对象,可回收的对象(红色),然后清除阶段 对可回收的对象进行回收清除
      image.png
2.1 标记清除算法的缺点
  • 标记清除效率 不稳定
    • 标记出来需要回收的对象,如果此时有大量的对象要回收,那么就需要大量的标记和清除动作,所以就会导致导致标记和清除两个过程的执行效率都随对象数量增长而降低
    • 当对象超出限制的时候,那么就会因为没有及时的清除而导致对象无法回收,效率不稳定
    • 清除可回收对象后,区域之间是不连续的,会产生大量不连续的内存碎片,空间碎片太多可能会导致需要分配较大对象时无法找到足够的连续内存
    • 没有大空间就不得不提前触发再一次垃圾收集动作

3.标记-复制算法

标记复制算法,根据名字可以知道,他的垃圾回收过程中出 现了复制的操作?具体是复制什么操作呢?复制到哪里呢?下面我们讲解下

标记-复制算法

  • 采用的是"复制"算法来实现的,即每次只使用其中的一部分内存
  • 当这部分内存用完后将存活着的对象复制到另外一块内存上,接着清空刚才使用的那部分内存
  • 当另一部分内存满了的时候再用上一次清空后的那块内存,以此往复,来回切换
  • 对比标记清除算法,,因为他会把内存全部复制迁移到另一半区,记复制算法解决了内存碎片化的问题,不存在不连续的碎片内存

image.png

3.1 标记复制算法的缺点

标记复制算法把新生代分为了 Eden区/Survival区

  • Survival区分为 From区和To区 1:1
  • Eden/from/to 大小为8:1:1
  • 可用的90%,会存在10%的空闲区域资源浪费
  • 当存活的对象超出10%时的时候,Survival区放不下,就需要用老年代来存储,放到老年代中

所以标记-复制算法存在以下缺点

  • 内存中的对象存活率较高时,需要from/to来回复制大量存活对象,使得回收效率变低。
  • 如果不想造成严重的内存浪费,就需要有额外的空间进行分配
  • 内存利用率最大只能达到90%

4.标记-整理算法

标记-清除算法适用于新生代,对象用完直接清除掉,但是因为老年代中存活率较高,存放不下时需要额外的内存空间担保,清除不能解决问题,因为大部分对象都不需要清除,就是因为这个原因,所以才出现了标记整理算法

  • 过程和标记-清除算法一致,标记垃圾过程一样的,标记的都是存活对象
  • 但是也是有区别的,对于标记完成的对象,不是统一的进行清理
  • 而是将所有的存活对象全部向内存空间一端移动,然后直接清理掉边界以外的内存。

这样有什么好处? 内存区域都在一端,同样不存在内存地址碎片,而且整理后,内存地址连续,更方便的进行分配

image.png

4.1 标记-整理算法缺点
  • 标记整理针对老年代,老年代大部分都是存活对象
  • 对于大部分都为存活对象,将这些对象都进行移动并且更新引用这些对象操作比较耗时
  • 更新引用需要暂停用户线程来保证用户线程访问对象不会出错,简称STW,“Stop the Word”
  • 其实不止整理算法里面移动对象更新引用需要STW,清除算法和复制算法中的标记清除都需要STW,只不过时间短

上面我们讲了几种对象的标记,清除,整理,回收的机制,现在做如下总结

  • 标记-整理算法意味着GC的时候要移动对象更新对象的引用,产生STW
  • 标记-清除算法意味着内存碎片化,内存地址不连续,没法分配大对象
  • 标记-复制算法意味着内存可用度不高,始终存在from/to区域用于复制

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

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

相关文章

pandas读取Excel核心源码剖析,面向过程仿openpyxl源码实现Excel数据加载

📢作者: 小小明-代码实体 📢博客主页:https://blog.csdn.net/as604049322 📢欢迎点赞 👍 收藏 ⭐留言 📝 欢迎讨论! 今天我们将研究pandas如何使用openpyxl引擎读取xlsx格式的Excel的…

el-tabs嵌套el-upload使用

需求:1 .第一个标签展示固定字样,且不能删除,最少上传三张图片。 2. 其余标签双击可编辑字样,10字以内,可删除,均可上传图片。 3. 号按钮可点击添加标签,标签数量控制在10个以内。 4. 当标签下无…

一文学会VSCode代码同步至GitHub

一、上手GitHub 1. 了解GitHub 上手GItHub之前首先要了解一下GItHub的关键词,如下: (1) 仓库 (Repository) 仓库是用来存放项目代码,每一项目对应一个仓库。(2) 收藏 (Star) 收藏别人的仓库,方便自己查找。(3) 复制/克隆项目 (…

忆暖行动|“以前的住宿也没有这么好的环境,住的都是土房子,一下雨就哗哗掉墙皮”

常忆旧时苦 方思今日甜 新年将至,彩灯与烟火闪烁。值此佳节,我们去看望了一位65岁的退休教师,并与她进行了交谈,从奶奶的讲述中,我们了解到过去生活的不易,珍惜当下的美好生活。 迎接新年 为迎接新年&am…

base64、File、Blob、ArrayBuffer几种文件格式介绍以及互转

文章目录 关系介绍BlobFileFileReader二进制数组ArrayBuffer对象URL.createObjectURLbase64 转化file转base64blob转base64base64转blobbaes64转fileblob转fileblob转ArrayBufferfile转ArrayBuffer 关系 介绍 Blob 介绍 是一个不可变、原始数据的类文件对象本质上是js的对象 s…

后悔了怎么办 - undo日志

一、undo日志 概念: 把回滚时所需的东西都给记下来 二、事务id 给事务分配id的时机 (1)对于只读事务来说,只有在它第一次对某个用户创建的临时表执行增、删、改操作时才会为这个事务分配一 个 事务id ,否则的话是不…

4.3 转换与处理时间数据

4.3 转换与处理时间数据 4.3.1 转换字符串时间为标准时间1、Timestamp2、DatetimeIndex或者PeriodIndexDatetimeIndex与PeriodIndex函数及其参数说明 4.3.2 提取时间序列数据信息Timestamp类常用属性及说明 4.3.3 加减时间数据Timedelta类周期名称、对应单位及其说明 4.3.4 任务…

Java知识总结

https://www.bilibili.com/video/BV1ys4y1S7Lc 1、Java中线程的实现方式 为什么说本质上只有一种实现线程的方式?实现 Runnable 接口究竟比继承 Thread 类实现线程好在哪里? 实现 Runnable 接口 public class RunnableThread implements Runnable { O…

ai智能改写文案-ai同义转换

文案创作是现代广告营销中不可或缺的一环,一个好的文案不仅可以提升产品的购买率,还可以实现品牌等方面的推广。但是,文案的创作需要耗费大量的时间和精力,如果能够利用智能化技术进行改写,不仅可以大大缩短文案创作时…

JAVA内存不足导致频繁回收和swap引起的性能问题 故障重现(内存篇2)

背景起因: 记起以前的另一次也是关于内存的调优分享下 有个系统平时运行非常稳定运行(没经历过大并发考验),然而在一次活动后,人数并发一上来后,系统开始卡。 我按经验开始调优,在每个关键步骤…

本地安装directus

简介 Directus 是用于管理 SQL 数据库内容的实时 API 和 App 控制面板。 API会根据数据库模式/内容的实时更改动态更新(无需重新启动服务器)。 Directus安装在任何新的或现有的 SQL 数据库之上,提供 API 层(REST、GraphQL、JS-SD…

获取商品SKU信息API调用代码展示、请求参数和返回值说明

SKU是什么意思 最小存货单位(SKU),全称为stock keeping unit,即库存进出计量的基本单元,可以是以件、盒、托盘等为单位。SKU这是对于大型连锁超市DC(配送中心)物流管理的一个必要的方法。现在已…

MySQL数据库从入门到精通学习第2天(创建数据库)

创建数据库 通过CREATE DATABASE语句来创建数据库通过CREATE SCHEMA语句来创建数据库通过IF NOT EXISTS进行判断创建 通过CREATE DATABASE语句来创建数据库 创建数据库的语法格式如下: CREATE DATABASE 【数据库名】; 创建数据库的库名跟标识符一样也是有要求的&…

实际项目集成分布式一致性协议 Raft

实际项目集成分布式一致性协议 Raft 文章目录 实际项目集成分布式一致性协议 Raft前言1.raft 是什么?2.SOFAJRaft2.1 功能特性 3.Nacos 分布式一致性设计3.1 nacos 分布式协议架构设计3.1 nacos 用 jraft 做什么3.2 Distro 协议 4.实际项目-Spring 工程4.1 旧版项目…

SA168 3BSE003389R1

SA168 3BSE003389R1 远程终端控制系统(RTU)可连接到其他设备。RTU可将设备上的电气信号转换为数字的值,例如一个开关或阀开/关的状态,或是仪器量测到的压力、流量、电压或电流。也可以借由信号转换及传送信号来控制设备&#xff0…

硬盘分区怎么分?新手该如何操作?

相信很多电脑用户都遇到过硬盘分区的情况。刚拿到手的新电脑,基本上都是一个或两个磁盘分区,这不满足我们的使用习惯,比如我们在不同的分区存放不同的东西,只有一个分区就很难做到,所以这时候需要进行磁盘分区。那么硬…

解读“SAP集成架构咨询方法论”

如果你是SAP ERP相关工作的,建议大家点开原文地址去看,会学习到其他很多与这个行业更多的资料。 原文地址:解读“SAP集成架构咨询方法论” | SAP Blogs 原文地址:解读“SAP集成架构咨询方法论” | SAP Blogs ——————————…

经验分享:如何有效应对Facebook广告数据波动问题?

Facebook广告作为一种重要的数字营销工具,可以帮助企业和品牌快速获得目标受众的关注和转化。然而,由于广告投放过程的不稳定性,Facebook广告数据波动问题也经常出现。 对于广告主而言,如何应对Facebook广告数据波动问题&#xf…

【JVM】JMM

一、JMM JVM 内存模型是用来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让 Java 程序在各个平台下都能达到一致的内存访问效果。JVM 内存模型规定了所有的共享变量都是存储在主内存,每个线程还有自己的工作内存,线程的工作内存保存了该线…

【教学类-34-01】拼图(运动项目)3*4格子(中班主题《个别化拼图》健康偏艺术-美术)

背景需求: 一个月的Python纸类学具研究中,我发现个别男孩喜欢把作业中的数字、图案、单元格剪成小块(小卡片)进几周,剪条、剪块的孩子人数也慢慢递增。 幼儿需求:锻炼手指精细动作的需求、或者获得更多物…