Java垃圾收集机制

news2025/1/21 18:56:03

目录

前言

判断对象是否存活

引用计数算法

可达性分析算法

GC Root的产生

Java中的四种引用类型

1.强引用

强引用弱化方式

方式1:使对象指向null

方式2:使对象超出作用域范围

2.软引用

3.弱引用

4.虚引用

垃圾收集算法

分代收集理论

垃圾收集算法分类

1.标记-清除算法(Mark-Sweep)

标记-清除算法的特点或问题

2.标记-复制算法(Copying)

算法工作流程

标记-复制算法的特点

3.标记-整理算法(Mark-Compact)

算法工作流程

标记-整理算法的特点

总结

前言

Java中的垃圾收集器(Garbage Collector)负责管理堆内存中的对象,回收不再使用的对象以释放内存空间。

判断对象是否存活

垃圾收集器工作的前提是该对象确实为一个垃圾对象,因此在 回收前需要进行判断,这里有两种方式可以对对象进行判断,分别是引用计数算法和可达性分析算法

引用计数算法

引用计数算法是通过在对象中添加一个引用计数器,来记录该对象被其他对象引用的次数,当计数器为0的时候,表示该对象没有被其他对象引用,是一个可回收的垃圾对象。

当然,这种算法存在一个较明显的问题,就是无法应对对象的循环引用,例如a 对象引用了 b 对象,b 对象也引用了 a 对象,ab 对象却没有再被其他对象所引用了,其实正常来说这两个对象已经是垃圾了,因为没有其他对象在使用了,但是计数器内的数值却不是 0,所以引用计数算法就无法回收它们。

可达性分析算法

可达性分析算法是通过引用链确认对象是否可用,也就是说在引用链上的对象即为可用对象,否则为垃圾对象。在该引用链上定义了“GC Root”起始节点集,引用链上的每个对象都可以通过GC Root找到。

例如下图中,Object 6Object 7Object 8彼此之前有引用关系,但是没有与"GC Roots"相连,那么就会被当做垃圾所回收。

GC Root的产生

  1. 栈帧中的本地变量和参数:正在执行的方法中的本地变量和参数可以作为GC Root,因为它们是当前线程活动的一部分。
  2. 静态变量:类的静态变量通常存储在方法区中,它们随着类的加载而被创建,并且在整个程序运行期间一直存在,因此它们被视为GC Root。
  3. 虚拟机内部的特殊引用:例如常量引用、系统类加载器等。
  4. JNI引用:在Java代码中使用了JNI(Java Native Interface)时,如果在本地代码中使用全局引用或弱全局引用,它们也会作为GC Root。

Java中的四种引用类型

垃圾回收器的工作时机除了与本身使用的算法相关,还与对象本身的引用类型相关。

1.强引用

强引用是最常使用的引用,通常是指向new 出来的对象的引用 例如 Object strongReference = new Object();,对于强引用,垃圾回收器是绝对不会进行回收操作的。就算是在内存空间不足的情况下,JVM也会通过抛出OutOfMemory来终止程序,而非回收强引用。

强引用弱化方式

强引用对象也存在不使用的情况,它的回收需要通过弱化,从而使垃圾回收器回收

方式1:使对象指向null

此时垃圾回收器会认为该对象不存在引用,然后根据GC算法对该对象进行回收。

例如:ArrayList集合的clear方法,就是通过遍历数组,将数组中的每个引用都指向null,使垃圾回收器能够对对象进行回收,达到清空的效果。

方式2:使对象超出作用域范围

在Java中,对象的作用域通常由大括号({})来定义,包括类、方法和代码块。当对象的作用域结束时,即离开了其定义的代码块或方法,该对象就会超出其作用域范围。

简单来说就是当一个对象在其作用域内被创建时,在该作用域范围内,可以通过引用来访问和操作该对象。但是一旦离开了对象的作用域,该对象就不能再通过原有的引用来访问和操作了。比如说对象对象定义在方法内,当方法执行结束,JVM方法栈中的活动栈帧弹出时,该对象也就不在作用域范围内了。

2.软引用

软引用也是一种较强的引用类型,与强引用的不回收不同,软引用可以在内存空间补不足时被垃圾回收器回收。通常用于内存敏感内容的高速缓存。

举个例子,在下图中,模拟了一个软引用,分别测试内存溢出与内存不溢出的情况下,断开引用后,软引用中的值

内存充沛

内存不足

在上面的例子上我们可以看到,当内存充足的情况下,即使软引用指向null,也不会被回收,一旦内存不足,软引用则被回收。

3.弱引用

弱引用是一种比软引用更弱的引用类型,与软引用不同,弱引用在下一次垃圾回收时一定会被垃圾回收器回收,无论内存是否充足。

4.虚引用

虚引用是最弱的一种引用关系,如果一个对象仅持有虚引用,完全不会对其生存时间构成影响,它就和没有任何引用一样,随时可能会被回收。主要用来跟踪对象被垃圾回收的活动,可以在垃圾收集时收到一个系统通知。

JDK1.2 之后,用 PhantomReference类来表示,通过查看这个类的源码,发现它只有一个构造函数和一个 get() 方法,而且它的 get() 方法仅仅是返回一个null,也就是说将永远无法通过虚引用来获取对象。

垃圾收集算法

说到垃圾收集算法就不得不说一个重要理论,即分代收集理论。下文详细介绍:

分代收集理论

分代收集理论基于一个观察:将对象的生命周期通常可以被划分为不同的阶段或代。根据对象的生命周期,垃圾回收器可以将内存划分为不同的代,然后针对不同代的对象应用不同的垃圾回收策略。目前主流JVM的垃圾收集器都遵循分代收集理论。

一般来说,分代收集理论将内存划分为至少两个代:年轻代、老年代

这是由于大部分对象在被创建后一段时间内会被频繁使用,但随着时间的推移,它们的生命周期会逐渐延长。因此,分代收集理论认为大部分对象是临时的,并且在它们的年轻阶段就会被回收,而只有部分对象会存活更久并进入老年代。

年轻代

被创建后一段时间内会被频繁使用,但随着时间的推移,它们的生命周期会逐渐延长。因此,分代收集理论认为大部分对象是临时的,并且在它们的年轻阶段就会被回收,而只有部分对象会存活更久并进入老年代。

老年代

在老年代中,垃圾回收器采用更长的回收周期和较少的垃圾回收操作。这是因为老年代中的对象通常具有较长的生命周期,并且相对稳定。典型的垃圾回收策略是标记-清除(Mark-Sweep)或标记-压缩(Mark-Compact)算法,其中垃圾回收器会标记并清除或压缩无效的对象,并回收相应的内存空间。

垃圾收集算法分类

1.标记-清除算法(Mark-Sweep)

标记-清除算法的整个工作过程可以分为两个阶段,分别是“标记”和“清除”。在标记阶段,首先垃圾收集器会标记出所有不需要回收的对象(这可以通过在对象的头部添加一个标记位来实现),然后进入清除阶段,将未标记的对象回收。

标记-清除算法的特点或问题

A.效率问题:

如果执行垃圾收集的区域中,大部分对象是需要被回收的,则需要哦执行大量的标记和清除操作,导致效率变低。

B.内存空间问题:

标记清除后会产生大量不连续的碎片,空间碎片太多,会导致分配较大对象时,无法找到足够的连续空间,从而会触发新的垃圾收集动作。

C.暂停时间:

在标记和清除阶段中,垃圾回收器需要停止应用程序的执行,这可能导致较长的停顿时间,影响应用的响应性。

2.标记-复制算法(Copying)

标记-复制算法在内存上的维护上,将空间分成两个大小相同的区域,通常称为对象区域和空闲区域。

算法工作流程
  1. 初始化时,所有对象都在对象区域。
  2. 从根对象开始,标记所有可达对象,将其从对象区域复制到空闲区域,并在新位置上更新引用。
  3. 完成复制后,对象区域中所有未被复制的对象都被认为是垃圾。
  4. 清空对象区域,并将空闲区域与对象区域交换,使空闲区域变为下一次垃圾回收的对象区域。
  5. 重复上述过程,进行下一轮的垃圾回收。

标记-复制算法的特点

A.高效的分配:

由于复制过程中对象是连续存放的,新对象的分配只需要简单的移动指针,效率较高。

B.暂停时间可控:

由于只需要复制存活对象,标记阶段的垃圾回收工作量相对较小,可以有效限制暂停时间。

C.内存利用率相对较低:

标记-复制算法会将堆内存的一半用于复制存活对象,因此相对于标记-清除算法会有一定的内存浪费。

D.效率降低

在对象存活率较高的情况下,需要进行较多内存间复制,导致效率降低

3.标记-整理算法(Mark-Compact)

标记-整理算法的主要思想是在标记阶段标记所有可达对象,并在标记完成后进行整理。整理阶段会将存活的对象向一端移动,然后清理掉边界之外的无效对象,以达到内存整理的目的。

算法工作流程
  1. 从根对象开始,标记所有可达对象。
  2. 在标记完成后,将存活对象向一端移动,并保持它们的相对顺序不变。这样,所有存活对象就在内存的一段连续区域中。
  3. 在移动过程中,将无效对象所占用的内存空间进行回收。可以通过向移动后存活对象的新位置复制数据来完成这一步骤。
  4. 清理掉边界之外的无效对象所占用的内存空间,使其变为可用于分配新对象的空闲内存。
标记-整理算法的特点

A.解决内存碎片化:

通过将存活对象移动到一端,并清理边界之外的无效对象,可以实现内存的整理,解决内存碎片问题。

B.高效的分配:

由于整理后存活对象在一段连续区域中,新对象的分配只需要简单的移动指针,效率较高。

C.暂停时间可控:

标记-整理算法的标记和整理阶段可以分别进行,可以有效限制暂停时间。

总结

标记-整理算法适用于老年代,而在年轻代通常采用其他垃圾回收算法,如标记-复制算法或其他更适合的算法。标记-整理算法通常与年轻代的标记-复制算法或其他算法配合使用,以实现整个堆的高效垃圾回收。

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

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

相关文章

Linux内核及可加载内核模块编程

图1 Linux系统整体结构 图2 Linux的源代码结构 下面显示一段内核模块代码案例&#xff1a; #include <linux/moduLe.h> #include <linux/kernel.h #include <linux/intt.h> /*模块的初始化函数lkp_ init()_init是用于初始化的修饰符 */ static int __init lk…

第十五届全国大学生数学竞赛报名快要截止了,你报上名了吗?

关于组织参加 第十五届全国大学生数学竞赛的通知 01 为了培养人才、服务教学、提高大学生学习数学的兴趣&#xff0c;培养学生分析问题、解决问题的能力&#xff0c;发现和选拔数学创新人才&#xff0c;为学生提供一个展示基础知识和思维能力的舞台&#xff0c;我校决定组织参…

SSM整合demo及个人思考

SSM整合 项目整体架构说明1. 创建Maven项目2. 配置web.xml4. 配置springmvc.xml5. 配置spring.xml6. 配置mybatis-config.xml以及创建mapper接口和mapper配置文件7. 配置log4j.xml8. 后端CURD测试8.1 在数据库中插入数据8.2 pojo中的实体类Employee8.3 mapper层的EmployMapper接…

oppo手机便签隐藏了一条怎样打开?手机如何找到隐藏便签?

有不少用户在使用OPPO手机的过程中&#xff0c;遇到了一些问题&#xff0c;例如自己在使用手机系统便签应用时&#xff0c;把一条重要的便签设置了隐藏&#xff0c;但是现在找不到隐藏的便签了。 那么oppo手机便签隐藏了一条怎样打开&#xff1f;OPPO手机如何找到隐藏便签&…

【C++】基础知识点回顾 上:命名空间与输入输出

前言 学习C一段时间后&#xff0c;再回过头来看这些C的基础知识&#xff0c;感觉有很多细节是自己当时没有注意的&#xff0c;所以写一篇文章来回顾复习一下C的基础知识。 命名空间的使用 相信很多朋友在学习C的第一个代码的时候&#xff0c;在写上头文件之后&#xff0c;紧…

运营商大数据实时获取精准数据

随着大数据技术的快速发展和完善&#xff0c;出现了一种新的扩张方式——互联网大数据的精准扩张。如果没有一个好的渠道来获得顾客&#xff0c;这就像准备热情地做饭&#xff0c;但当饭吃完后&#xff0c;人们只能饿了。 今天的消费者已经从最早的线下消费逐渐过渡到互联网消…

浅谈6种API架构模式

在摸鱼刷X时&#xff0c;看到一张非常棒的图&#xff0c;是关于不同API架构的&#xff0c;下面学习记录一下。 &#xff08;摘自网络&#xff09; 1、gRPC gRPC是一种高性能、跨语言、易扩展的远程过程调用(RPC)框架&#xff0c;可用于分布式系统之间的通信。gRPC被广泛地应用…

金融贷款行业实时高精准获客 ——三网运营商大数据

都说生产是第一因素&#xff0c;但对于任何企业来说&#xff0c;客户来源才是第一因素。 在大多数行业&#xff0c;获得客户的困难已经成为行业的挑战。如今&#xff0c;许多行业和企业获得客户的主要来源是在线促销和客户获取。现在几乎每个人都有一部手机。运营商可以根据移…

每日一练 | 网络工程师软考真题Day33

阅读以下说明&#xff0c;答复以下【问题1】和【问题2】 【说明】 某单位内部网络拓扑结构如图5-1所示&#xff0c;在该网络中采用RIP路由协议。 【问题1】 1&#xff0e;路由器第一次设置时&#xff0c;必须通过Console口连接运行终端仿真软件的微机进行配置&#xff0c;此时…

ByteV联合“智农”打造--数字孪生大棚可视化

ByteV联合“智农”打造的数字孪生大棚可视化&#xff0c;不仅要让粮食稳产、增产&#xff0c;更要对土壤肥力进行改良和提升。不仅能够实现科技引领农业发展&#xff0c;更在智慧农业的基础上实现一站式托管&#xff0c;真正做到技术提升、5G引领、建后管护的闭环管理。让高标准…

预测多基因扰动的转录结果

了解细胞对基因扰动的反应是许多生物医学应用的核心&#xff0c;从识别癌症中涉及的基因相互作用到开发再生医学方法。然而&#xff0c;可能的多基因扰动数量的组合爆炸严重限制了实验验证。在这里&#xff0c;作者提出了图增强的基因激活和抑制模拟器&#xff08;GEARS&#x…

Linux内核4.14版本——drm框架分析(13)——DRM_IOCTL_MODE_SETPLANE(drm_mode_setplane)

目录 1. drm_mode_setplane 1.1 根据应用的plane_req->plane_id找到plane 1.2 根据应用的plane_req->fb_id找到struct drm_framebuffer 1.3 调用setplane_internal 2. setplane_internal->__setplane_internal 2.1 struct drm_framebuffer是否为空 2.2 判断此p…

Cesium对WMS地图服务进行查询并弹框展示信息

一、简介 Cesium加载WMS地图服务&#xff0c;然后调用接口GetFeatureInfo对要素信息进行查询 二、测试接口 {type: "Point | MultiPoint | LineString | MultiLineString | Polygon | MultiPolygon",coordinates: 数组 } 查询点 http://123.56.67.147:8080/geoserve…

智慧公厕构建城市公共厕所中枢网络,民生服务更高效,城市管理更精准

随着城市化进程的加快&#xff0c;城市人口的不断增长&#xff0c;城市公共厕所问题愈发凸显。大量的人口涌入&#xff0c;公厕资源的不足、管理的不到位&#xff0c;已经成为困扰城市发展的一大难题。然而&#xff0c;智慧公厕的出现&#xff0c;为解决这一问题提供了新的思路…

2023-09-12 LeetCode每日一题(课程表 IV)

2023-03-29每日一题 一、题目编号 1462. 课程表 IV二、题目链接 点击跳转到题目位置 三、题目描述 你总共需要上 numCourses 门课&#xff0c;课程编号依次为 0 到 numCourses-1 。你会得到一个数组 prerequisite &#xff0c;其中 prerequisites[i] [ai, bi] 表示如果你…

这泼天的富贵,轮到数字化转型升级的企业了

数字化转型是建立在现代信息技术上&#xff0c;利用数字化的一切相关技术创建一种新的、或者对已有的商业模式进行重塑&#xff0c;以此来满足时代变化中传统的业务和市场进行变革。 数字化转型 - 派可数据BI可视化分析平台 出现这种变革是因为经过几十年的经济发展&#xff0…

怎么合并pdf文件到一起?快点过来尝试一下吧

怎么合并pdf文件到一起&#xff1f;pdf文件的使用越来越频繁&#xff0c;相信每个小伙伴都有这样的感受&#xff0c;不管是网上下载到的文件资料&#xff0c;还是合作伙伴发送过来的合作意向书&#xff0c;基本上都会做成pdf格式的文件&#xff0c;因为pdf文件具有更强的稳定性…

记账app排行榜前十名,第2个开店必备!

工欲善其事必先利其器&#xff0c;不管是开店做生意的老板还是个人&#xff0c;想要管理好自己的财富&#xff0c;第一步就是要坚持记账。 现在市面上的记账App有很多&#xff0c;我们选取了秦丝进销存、随手记、智慧记等10款比较有代表性的记账APP&#xff0c;其中有几个是专…

webpack自定义loader解析指定后缀名文件

案例&#xff1a; webpack自定义loader解析.chenjiang后缀名的文件 整体目录&#xff1a; chenjiangLoader.js文件代码 // 正则匹配script标签中的内容 const REG /<script>([\s\S]*)<\/script>/;module.exports function (source) {const __source source.…

拼多多手势验证

国内的好像并没有出现这种&#xff0c;一般都是在海外注册&#xff0c;或者发信才会有。各位大哥想研究的话得需要挂vpn了。 拼多多手势的轨迹其实咋说&#xff0c;难倒是不难&#xff0c;反正要你准确按这个线条描绘出不间断的数据。 它这识别的话&#xff0c;跟狗东的那个还…