当前位置: 首页 > news >正文

【JVM】垃圾回收机制(Garbage Collection)

目录

一、什么是垃圾回收?

二、为什么要有垃圾回收机制(GC)?

三、垃圾回收主要回收的内存区域

四、死亡对象的判断算法

a)引用计数算法

b)可达性分析算法

五、垃圾回收算法

a)标记-清除算法

b)复制算法

c)标记-整理算法

d)分代算法

六、垃圾回收器


一、什么是垃圾回收?

垃圾回收指的是自动管理和释放不再被程序使用的内存资源的过程。在程序运行过程中,动态分配的内存会被使用,但也需要在不再需要时释放,以免占用过多的内存空间,导致内存泄漏或内存溢出等问题。

二、为什么要有垃圾回收机制(GC)?

早在学习C语言中,有这么一块内容:动态内存管理。动态内存管理的主要内容就是通过 malloc 申请内存,free 释放内存。

  • 此处 malloc 申请到的内存,生命周期是跟随整个进程的。
  • 这一点对于服务器程序就很不友好了,服务器每个请求都去 malloc 一块内存,如果没有 free 释放,就会使申请的内存越来越多,后续想要申请内存就无法申请了。这就是内存泄漏问题。

而在实际开发中,很容易出现 free 不小心就忘记调用了,或者因为一些情况导致 free 没有被执行到,例如代码块中存在 if 导致的 return 或者 抛出异常了(当前C语言没有异常这一说)。因此,内存泄漏是一个很大的问题。

能否让释放内存的操作,由程序自动负责完成,而不是依赖程序员手动释放呢?

  • 此时就引入了垃圾回收机制(GC),来解决上述问题。

三、垃圾回收主要回收的内存区域

JVM 在运行 Java 程序时,将内存划分为不同的区域,称为运行时数据区。这些区域包括方法区、堆、栈(虚拟机栈)、本地方法栈和程序计数器等。程序在执行之前先要把 Java 代码转换成字节码(.class文件),JVM 首先需要把字节码通过一定的方式(类加载器)把文件加载到内存中(即运行时数据区)。

对于程序计数器、虚拟机栈、本地方法栈这三部分区域而言,其生命周期与相关线程有关,随线程而生,随线程而灭。并且这三个区域的内存分配与回收具有确定性,因为当方法结束或者线程结束时,内存就自然跟着线程回收了。

而对于方法区,方法区主要存储的是类加载后的元数据信息(静态变量,常量池等),这些信息在程序运行期间基本上是不会发生变化的。

因此,在Java虚拟机中,垃圾回收主要针对的是 堆 区域进行回收。

前面说到,垃圾回收指的是自动管理和释放不再被程序使用的内存资源的过程,在Java堆中,存放着几乎所有的对象实例,因此内存回收,也可以叫做死亡对象的回收。

垃圾回收器在对堆进行垃圾回收前,首先要判断这些对象哪些还存活,哪些已经“死去”。判断对象是否已“死”有以下几种算法。

四、死亡对象的判断算法

a)引用计数算法

引用计数法的描述如下: 

  • 引用计数算法是一种简单的垃圾回收算法,它基于对象的引用计数来确定何时可以回收对象。在引用计数算法中,每个对象都会有一个与之关联的引用计数,用来记录有多少个指针指向该对象。当引用计数为0时,表示该对象不再被引用,可以安全地回收。
  • 这种算法的实现相对简单,通常在对象创建和销毁时维护引用计数。当有新的指针指向对象时,引用计数加1;当指针不再指向对象时,引用计数减1。当引用计数减到0时,垃圾回收器会立即回收该对象。

引用计数算法的优点是实现简单,且判定效率也比较高,可以及时回收不再使用的对象。比如Python语言就采用引用计数法进行管理内存。

但是,在主流的JVM中没有选用引用计数法来管理内存,最主要的原因就是引用计数法无法解决对象的循环引用问题。即如果两个或多个对象之间存在循环引用,它们的引用计数永远不会为0,即使它们已经不再被程序使用,也无法被回收。这会导致内存泄漏,占用大量的内存空间。

b)可达性分析算法

JVM 就是采用“可达性分析”来判断对象是否存活(同样采用此法的还有C#、Lisp),该算法可以有效处理循环引用问题,其核心思想为:

  • 通过一系列称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索(遍历),搜索走过的路径称之为“引用链”,当一个对象到GC Roots没有任何的引用链相连时(从GC Roots到这个对象不可达),证明此对象是不可用的。
  • 一旦完成了可达性分析,JVM 就可以安全地回收那些不可达的对象,释放它们所占用的内存空间。

如上图所示,对象Object5-Object7之间虽然彼此还有关联,但是它们到GC Roots是不可达的,因此它们会被判定为可回收对象。

★在Java语言中,可作为GC Roots的对象包含下面几种:

  1. 虚拟机栈(栈帧中的本地变量表)中引用的对象;
  2. 方法区中类静态属性引用的对象;
  3. 方法区中常量引用的对象;
  4. 本地方法栈中 JNI(Native方法)引用的对象。

通过可达性分析算法,JVM 就能够将死亡对象标记出来了,标记出来之后就要进行垃圾回收操作。在介绍垃圾回收器之前,先介绍垃圾回收器使用的几种算法。

五、垃圾回收算法

a)标记-清除算法

“标记-清除”算法是最基础的垃圾回收算法。算法分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。

后续的回收算法都是基于这种思路,并对其不足加以改进而已。

“标记-清除”算法的不足主要有两个:

  1. 效率问题:标记和清除这两个过程的效率都不高,特别是在堆中对象数量庞大的情况下。
  2. 空间问题:标记清除后会产生大量不连续的内存碎片,内存碎片太多可能会导致以后在程序运行中,需要分配较大对象时,无法找到足够连续的内存而导致内存分配失败,或不得不提前触发另一次垃圾回收。

b)复制算法

“复制”算法解决了“标记-清除”算法两个主要问题,即内存碎片化问题和效率问题。

  • 它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。
  • 当这块内存需要进行垃圾回收时,会将此区域还存活着的对象复制到另一块上面,然后再把已经使用过的内存区域一次清理掉。

这样做的好处就在于不仅解决了“标记-清除”的主要问题,且算法实现简单,运行高效。解决内存碎片化问题主要体现在,复制过程中通过移动堆顶指针,按顺序进行分配,使碎片化内存被复制到连续的一块空间。

不过,复制算法也有一些缺点:例如在一轮GC中,大部分对象都是长期存活的,只有少数对象需要回收,那么复制算法就会造成大量的复制操作,导致影响性能。

c)标记-整理算法

“标记-整理”算法的提出,则是为了解决“复制”算法在对象存活率较高时,会进行比较多的复制操作这样的问题。

  • 标记过程仍与“标记-清除”算法的标记过程一致;
  • 但后续步骤不是直接对可回收对象进行回收,而是让所有存活对象都向一端移动,以便整理出一块连续的内存空间。这个思想类似于双指针算法,但其移动对象的过程更复杂。

上述过程仍有一些缺点:即移动存活对象的过程会带来较大的开销。

d)分代算法

综合以上三种算法,JVM并没有直接使用其中的一种,而是结合这三种算法,搞出了一个“综合性”方案,即分代算法。

实际上,堆里面分为两个区域:新生代和老生代,新生代放新建的对象,当经过一定 GC 次数之后还存活的对象才放入老生代。新生代还有三个区域:一个 Endn + 两个 Survivor(S0/S1).

分代算法就是通过区域划分,实现不同区域使用不同的的垃圾回收策略,从而实现更好的垃圾回收。

这就好比中国的一国两制方针一样,对于不同的情况和地域设置更符合当地的规则,从而实现更好的管理,这就是分代算法的设计思想。 

当前 JVM 垃圾回收都采用的是“分代”算法。在新生代中,每次垃圾回收都有大批的对象死去,只有少量存活,因此采用复制算法;而老年代中对象存活率高、没有额外空间对它进行分配担保,就必须采用“标记-清除”或者“标记-整理”算法。

  • 对于新生代来说,98%的对象都是“朝生夕死”的,所以并不需要按照1:1的比例来划分内存空间,而是将新生代内存分为一块比较大的Eden(伊甸园)空间和两块比较小的Survivor(幸存者)空间,每次使用Eden和其中一块Survivor(两个Survivor区域,一个称为From区,一个称为To区)。
  • 当回收时,将Eden和Survivor中还存活的对象一次性复制到另一块Survivor上,最后清理掉Eden和刚才使用过的Survivor空间。完成一次对象复制后,From区和To区的角色会互换。
  • HotSpot虚拟机默认Eden与Survivor的大小比例是8:1,也就是说Eden:Survivor From:Survivor To = 8:1:1。所以每次新生代可用内存空间为整个新生代容量的90%,而剩下的10%用来存放回收后存活的对象。

哪些对象会进入新生代?哪些对象会进入老年代?

  • 新生代:一般新创建的对象都会进入新生代;
  • 老年代:大对象和经历了 N 次(一般情况默认是 15 次)垃圾回收依然存活下来的对象会从新生代移动到老年代。

面试题:请问了解 Minor GC 和 Full GC 吗?这两种GC有什么不一样吗?

  • Minor GC又称为新生代GC,指的是发生在新生代的垃圾回收。因为新生代中的Java对象大多都具有朝生夕灭的特性,因此Minor GC(采用复制算法)非常频繁,一般回收速度也比较快。
  • Full GC又称为老年代GC或者Major GC:指发生在老年代的垃圾回收。出现了Major GC,经常会伴随至少一次的Minor GC(并非绝对)。Major GC的触发频率通常比较低,且速度一般会比Minor GC慢10倍以上。

六、垃圾回收器

如果说上面所讲的垃圾回收算法是内存回收的方法论,那么垃圾回收器就是内存回收的具体实现。

垃圾回收器的作用:垃圾回收器是为了保证程序能够正常、持久运行的一种技术,它是将程序中的死亡对象,也就是垃圾对象进行清除,从而保证了新对象能够正常申请到内存空间。

以下这些回收器是 HotSpot 虚拟机随着不同版本推出的重要的垃圾回收器:

上图展示了7种作用于不同分代的垃圾回收器,如果两个回收器之间存在连线,就说明它们之间可以搭配使用。所处的区域,表示它是属于新生代回收器还是老年代回收器。

为什么会有这么多垃圾回收器?

  • 其主要原因是:自从有了 Java 语言就有了垃圾回收器,这么多垃圾回收器其实是历史发展的产物。随着时间的推移和技术的进步,人们对垃圾回收器的性能、吞吐量、停顿时间等方面提出了更高的要求,因此就产生了更多更新的垃圾回收器。

此处就不展开介绍每种垃圾回收器了。

相关文章:

【JVM】垃圾回收机制(Garbage Collection)

目录 一、什么是垃圾回收? 二、为什么要有垃圾回收机制(GC)? 三、垃圾回收主要回收的内存区域 四、死亡对象的判断算法 a)引用计数算法 b)可达性分析算法 五、垃圾回收算法 a)标记-清除…...

C++中的priority_queue模拟实现

目录 priority_queue模拟实现 priority_queue类定义 priority_queue构造函数 priority_queue类push()函数 priority_queue类pop()函数 priority_queue类size()函数 priority_queue类empty()函数 priority_queue类top()函数 仿函数与priority_queue类模拟实现 仿函数 …...

【Kafka】1.Kafka核心概念、应用场景、常见问题及异常

Kafka 是一个分布式流处理平台,最初由 LinkedIn 开发,后成为 Apache 软件基金会的顶级项目。 它主要用于构建实时数据管道和流式应用程序。它能够高效地处理高吞吐量的数据,并支持消息发布和订阅模型。Kafka 的主要用途包括实时分析、事件源、…...

LTE的EARFCN和band之间的对应关系

一、通过EARFCN查询对应band 工作中经常遇到只知道EARFCN而需要计算band的情况,因此查了相关协议,找到了他们之间的对应关系,可以直接查表,非常方便。 具体见: 3GPP TS 36.101 5.7.3 Carrier frequency and EAR…...

解决问题:Docker证书到期(Error grabbing logs: rpc error: code = Unknown)导致无法查看日志

问题描述 Docker查看日志时portainer报错信息如下: Error grabbing logs: rpc error: code Unknown desc warning: incomplete log stream. some logs could not be retrieved for the following reasons: node klf9fdsjjt5tb0w4hxgr4s231 is not available报错…...

【C语言】预处理器

我们在开始编写一份程序的时候&#xff0c;从键盘录入的第一行代码&#xff1a; #include <stdio.h>这里就使用了预处理&#xff0c;引入头文件。 C预处理器不是编译器的组成部分&#xff0c;但是它是编译过程中一个单独的步骤。简言之&#xff0c;C预处理器只不过是一…...

QtConcurrent::run操作界面ui的注意事项(2)

前面的“QtConcurrent::run操作界面ui的注意事项&#xff08;1&#xff09;”&#xff0c;末尾说了跨线程的问题&#xff0c;引出了Qt千好万好&#xff0c;就是跨线程不好。下面是认为的最简单的解决办法&#xff1a;使用QMetaObject::invokeMethod&#xff08;相比较信号-槽&a…...

黑马程序员HarmonyOS4+NEXT星河版入门到企业级实战教程笔记

HarmonyOS NEXT是纯血鸿蒙&#xff0c;鸿蒙原生应用&#xff0c;彻底摆脱安卓 本课程是基于harmony os4的&#xff0c;与next仅部分api有区别 套件 语言&框架 harmony os design ArkTs 语言 ArkUI 提供各种组件 ArkCompiler 方舟编译器 开发&测试 DevEco Studio 开发…...

嵌入式全栈开发学习笔记---C语言笔试复习大全13(编程题9~16)

目录 9.查找字符数组中字符位置&#xff08;输入hello e 输出2&#xff09;&#xff1b; 10、查找字符数组中字符串的位置&#xff08;输入hello ll 输出3&#xff09;&#xff1b; 11、字符数组中在指定位置插入字符&#xff1b;&#xff08;输入hello 3 a 输出heallo…...

https网站安全证书的作用与免费申请办法

HTTPS网站安全证书&#xff0c;也称为SSL证书&#xff0c;网站通过申请SSL证书将http协议升级到https协议 HTTPS网站安全证书的作用 1 增强用户信任&#xff1a;未使用https协议的网站&#xff0c;用户访问时浏览器会有“不安全”弹窗提示 2 提升SEO排名&#xff1a;搜索引擎…...

自动化测试再升级,大模型与软件测试相结合

近年来&#xff0c;软件行业一直在迅速发展&#xff0c;为了保证软件质量和提高效率&#xff0c;软件测试领域也在不断演进。如今&#xff0c;大模型技术的崛起为软件测试带来了前所未有的智能化浪潮。 软件测试一直是确保软件质量的关键环节&#xff0c;但传统的手动测试方法存…...

centos7 基础命令

一、基础信息&#xff1a; 查看IP地址&#xff1a; ip add 重启网络服务&#xff1a; service network restart 查看网卡配置&#xff1a; cat /etc/sysconfig/network-scripts/ifcfg-ens33 启动网卡: ifup ens33 查看内存: free -m 查看CPU&#xff1a; cat /proc/cpuin…...

【设计模式】之单例模式

系列文章目录 【设计模式】之责任链模式【设计模式】之策略模式【设计模式】之模板方法模式 文章目录 系列文章目录 前言 一、什么是单例模式 二、如何使用单例模式 1.单线程使用 2.多线程使用&#xff08;一&#xff09; 3.多线程使用&#xff08;二&#xff09; 4.多线程使用…...

3d模型实体显示有隐藏黑线?---模大狮模型网

在3D建模和设计领域&#xff0c;细节决定成败。然而&#xff0c;在处理3D模型时&#xff0c;可能会遇到模型实体上出现隐藏黑线的问题。这些黑线可能影响模型的视觉质量和呈现效果。因此&#xff0c;了解并解决这些隐藏黑线的问题至关重要。本文将探讨隐藏黑线出现的原因&#…...

共享购:全新消费模式的探索与实践

在消费模式日益创新的今天&#xff0c;共享购模式以其独特的消费与收益双重机制&#xff0c;吸引了众多消费者的目光。这一模式不仅为消费者带来了全新的购物体验&#xff0c;也为商家和平台带来了可观的收益。 一、会员体系&#xff1a;共享购的基石 在共享购模式下&#xff…...

Java集合 总结篇(全)

Java集合 集合底层框架总结 List 代表的有序&#xff0c;可重复的集合。 ArrayList -- 数组 -- 把他想象成C中的Vector就可以&#xff0c;当数组空间不够的时候&#xff0c;会自动扩容。 -- 线程不安全 LinkedList -- 双向链表 -- 可以将他理解成一个链表&#xff0c;不支持…...

Dubbo分层架构深度解析

引言 Dubbo作为一款备受欢迎的高性能、轻量级的Java RPC框架&#xff0c;在现代分布式系统中扮演着至关重要的角色。随着互联网行业的快速发展&#xff0c;服务间的通信变得越来越频繁&#xff0c;这也使得对于高效、可靠的远程通信方案的需求变得愈发迫切。在这样的背景下&am…...

LocalDate 数据库不兼容问题,因为LocalDate 是 long 类型的

我今天遇到一报错&#xff1a; SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession316f9272] was not registered for synchronization because synchronization is not active JDBC Connection [HikariProxyConnection2127597288 wrapping com.mysql.cj.jdbc…...

RVM(相关向量机)、CNN_RVM(卷积神经网络结合相关向量机)、RVM-Adaboost(相关向量机结合Adaboost)

当我们谈到RVM&#xff08;Relevance Vector Machine&#xff0c;相关向量机&#xff09;、CNN_RVM&#xff08;卷积神经网络结合相关向量机&#xff09;以及RVM-Adaboost&#xff08;相关向量机结合AdaBoost算法&#xff09;时&#xff0c;每种模型都有其独特的原理和结构。以…...

Java--方法的使用

1.1什么是方法 方法顾名思义就是解决问题的办法&#xff0c;在程序员写代码的时候&#xff0c;会遇到很多逻辑结构一样&#xff0c;解决相同问题时&#xff0c;每次都写一样的代码&#xff0c;这会使代码看起来比较绒余&#xff0c;代码量也比较多&#xff0c;为了解决这个问题…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

DingDing机器人群消息推送

文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人&#xff0c;点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置&#xff0c;详见说明文档 成功后&#xff0c;记录Webhook 2 API文档说明 点击设置说明 查看自…...

接口自动化测试:HttpRunner基础

相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具&#xff0c;支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议&#xff0c;涵盖接口测试、性能测试、数字体验监测等测试类型…...

【网络安全】开源系统getshell漏洞挖掘

审计过程&#xff1a; 在入口文件admin/index.php中&#xff1a; 用户可以通过m,c,a等参数控制加载的文件和方法&#xff0c;在app/system/entrance.php中存在重点代码&#xff1a; 当M_TYPE system并且M_MODULE include时&#xff0c;会设置常量PATH_OWN_FILE为PATH_APP.M_T…...

毫米波雷达基础理论(3D+4D)

3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文&#xff1a; 一文入门汽车毫米波雷达基本原理 &#xff1a;https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing

Muffin 论文 现有方法 CRADLE 和 LEMON&#xff0c;依赖模型推理阶段输出进行差分测试&#xff0c;但在训练阶段是不可行的&#xff0c;因为训练阶段直到最后才有固定输出&#xff0c;中间过程是不断变化的。API 库覆盖低&#xff0c;因为各个 API 都是在各种具体场景下使用。…...

第八部分:阶段项目 6:构建 React 前端应用

现在&#xff0c;是时候将你学到的 React 基础知识付诸实践&#xff0c;构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段&#xff0c;你可以先使用模拟数据&#xff0c;或者如果你的后端 API&#xff08;阶段项目 5&#xff09;已经搭建好&#xff0c;可以直接连…...

Windows电脑能装鸿蒙吗_Windows电脑体验鸿蒙电脑操作系统教程

鸿蒙电脑版操作系统来了&#xff0c;很多小伙伴想体验鸿蒙电脑版操作系统&#xff0c;可惜&#xff0c;鸿蒙系统并不支持你正在使用的传统的电脑来安装。不过可以通过可以使用华为官方提供的虚拟机&#xff0c;来体验大家心心念念的鸿蒙系统啦&#xff01;注意&#xff1a;虚拟…...