JVM 垃圾回收机制:GC

news2024/9/25 17:20:19

目录

一、死亡对象的判断算法

1.1 引用计数算法

1.2 可达性分析算法

二、垃圾回收算法

2.1 标记-清除算法

2.2 复制算法

2.3 标记-整理算法

2.4 分代算法

三、垃圾收集器

3.1 CMS收集器(老年代收集器,并发GC)

3.2 G1收集器(唯一一款全区域的垃圾回收器)


JVM的垃圾回收机制:GC,是Java提供的对于内存自动回收的机制。

在 Java 中,所有的对象都是要存在内存中的(也可以说内存中存储的是一个个对象),因此将内存回收,也可以叫做死亡对象的回收。GC回收的是“堆上的内存”。

一、死亡对象的判断算法

1.1 引用计数算法

思想:

给对象增加一个引用计数器,每当有一个地方引用它时,计数器就+1;当引用失效时,计数器就-1; 任何时刻计数器为0的对象就是不能再被使用的,即对象已"死"。

引用计数法实现简单,判定效率也比较高,在大部分情况下都是一个不错的算法。比如Python语言就采用引用计数法进行内存管理。
在主流的JVM中没有选用引用计数法来管理内存,最主要的原因就是引用计数法无法解决对象的循环引用问题。

1.2 可达性分析算法

思想:

通过一系列称为"GC Roots"的对象作为起始点,从这些节点开始向下搜索,搜索走过的路径称之为"引用链",当一个对象到 GC Roots 没有任何的引用链相连时 (从GC Roots到这个对象不可达)时,证明此对象是不可用的。如下:
对象 Object5 - Object7 之间虽然彼此还有关联,但是它们到 GC Roots 是不可达的,因此他们会被判定为可回收对象。
在Java语言中,可作为 GC Roots 的对象包含下面几种:
  1. 虚拟机栈(栈帧中的本地变量表)中引用的对象;
  2. 方法区中类静态属性引用的对象;
  3. 方法区中常量引用的对象;
  4. 本地方法栈中 JNI(Native方法)引用的对象。
在 JDK1.2 时,Java 对引用的概念做了扩充,分为以下四种,这四种引用的强度依次递减:
  1. 强引用 : 强引用指的是在程序代码之中普遍存在的,类似于"Object obj = new Object()"这类的引用,只要强引用还存在,垃圾回收器永远不会回收掉被引用的对象实例。
  2. 软引用 : 软引用是用来描述一些还有用但是不是必须的对象。对于软引用关联着的对象,在系统将要发生内存溢出之前,会把这些对象列入回收范围之中进行第二次回收。如果这次回收还是没有足够的内存,才会抛出内存溢出异常。在JDK1.2之后,提供了SoftReference类来实现软引用。
  3. 弱引用 : 弱引用也是用来描述非必需对象的。但是它的强度要弱于软引用。被弱引用关联的对象只能生存到下一次垃圾回收发生之前。当垃圾回收器开始进行工作时,无论当前内容是否够用,都会回收掉只被弱引用关联的对象。在JDK1.2之后提供了WeakReference类来实现弱引用。
  4. 虚引用 : 虚引用也被称为幽灵引用或者幻影引用,它是最弱的一种引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。在JDK1.2之后,提供了PhantomReference类来实现虚引用

二、垃圾回收算法

2.1 标记-清除算法

"标记-清除"算法是最基础的收集算法。算法分为"标记"和"清除"两个阶段 : 首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。后续的收集算法都是基于这种思路并对其不足加以改进而已。
"标记-清除"算法的不足主要有两个 :
  • 效率问题 : 标记和清除这两个过程的效率都不高。
  • 空间问题 : 标记清除后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行中需要分配较大对象时,无法找到足够连续内存而不得不提前触发另一次垃圾收集。

2.2 复制算法

复制"算法是为了解决"标记-清理"的效率问题。
它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这块内存需要进行垃圾回收时,会将此区域还存活着的对象复制到另一块上面, 然后再把已经使用过的内存区域一次清理掉。这样做的好处是每次都是对整个半区进行内存回收,内存分配时也就不需要考虑内存碎片等复杂情况,只需要移动堆顶指针,按顺序分配即可。
此算法实现简单,运行高效。算法的执行流程如下图 :

2.3 标记-整理算法

复制收集算法在对象存活率较高时会进行比较多的复制操作,效率会变低。因此在老年代一般不能使用复制算法。 针对老年代的特点,提出了一种称之为"标记-整理算法"。标记过程仍与"标记-清除"过程⼀致,但后续步骤不是直接对可回收对象进行清理,而是让所有存活对象都向一端移动,然后直接清理掉端边界以外的内存。
流程图如下:

2.4 分代算法

分代算法和上面 3 种算法不同,分代算法是通过区域划分,实现不同区域和不同的垃圾回收策略,从而实现更好的垃圾回收。
当前 JVM 垃圾收集都采用的是" 分代收集(Generational Collection)" 算法,这个算法并没有新思想,只是根据对象存活周期的不同将内存划分为几块。
一般是把Java堆分为 新生代和老年代 。在新生代中,每次垃圾回收都有大批对象死去,只有少量存活,因此我们采用复制算法;而老年代中对象存活率高、没有额外空间对它进行分配担保,就必须采用"标记-清理"或者"标记-整理"算法。
哪些对象会进入新生代?哪些对象会进入老年代?
  • 新生代:一般创建的对象都会进入新生代;
  • 老年代:大对象和经历了 N 次(一般情况默认是 15 次)垃圾回收依然存活下来的对象会从新生代移动到老年代。
面试题 : 请问了解Minor GC和Full GC么,这两种GC有什么不一样吗?
  • Minor GC 又称为新生代GC : 指的是发生在新生代的垃圾收集。因为Java对象大多都具备朝生夕灭的特性,因此Minor GC(采用复制算法)非常频繁,一般回收速度也比较快。
  • Full GC 又称为老年代GC 或者 Major GC : 指发生在老年代的垃圾收集。出现了Major GC,经常会伴随至少一次的Minor GC (并非绝对,在Parallel Scavenge收集器中就有直接进行Full GC的策略选择过程)。Major GC的速度一般会比Minor GC慢10倍以上。

三、垃圾收集器

收集算法是内存回收的方法论,垃圾收集器是内存回收的具体实现。

垃圾收集器的作用:垃圾收集器是为了保证程序能够正常、持久运行的一种技术,它是将程序中不用的死亡对象也就是垃圾对象进行清除,从而保证了新对象能够正常申请到内存空间。
以下这些收集器是 HotSpot 虚拟机随着不同版本推出的重要的垃圾收集器:

上图展示了7种作用于不同分代的收集器,如果两个收集器之间存在连线,就说明他们之间可以搭配使用。所处的区域,表示它是属于新生代收集器还是老年代收集器。
  • 并行(Parallel) : 指多条垃圾收集线程并行工作,用户线程仍处于等待状态。
  • 并发(Concurrent) : 指用户线程与垃圾收集线程同时执行 (不一定并行,可能会交替执行),用户程序继续运行,而垃圾收集程序在另外一个CPU上。
  • 吞吐量:就是CPU用于运行用户代码的时间与CPU总消耗时间的比值。
  • 吞吐量 = 运行用户代码时间/(运行用户代码时间 + 垃圾收集时间)
例如:虚拟机总共运行了100分钟,其中垃圾收集花掉1分钟,那吞吐量就是99%。

3.1 CMS收集器(年代收集器,并发GC)

特性:

CMS(Concurrent Mark Sweep)收集器是种以获取最短回收停顿时间为标的收集器。前很大一部分的Java应集中在互联网站或者B/S系统的服务端上,这类应尤其重视服务的响应速度,希望系统停顿时间最短,以给用户带来较好的体验。CMS收集器就非常符合这类应的需求。

CMS收集器是基于“标记—清除”算法实现的,它的整个过程分为4个步骤:

1. 初始标记(CMS initial mark):初始标记仅仅只是标记一下GC Roots能直接关联到的对象,速度很快,需要“Stop The World”。

2. 并发标记(CMS concurrent mark):并发标记阶段就是进行GC Roots Tracing的过程。

3. 重新标记(CMS remark):重新标记阶段是为了修正并发标记期间因用户程序继续运作导致标记产变动的那部分对象的标记记录,这个阶段的停顿时间般会比初始标记阶段稍长一些,但远比并发标记的时间短,仍然需要“Stop The World”。

4. 并发清除(CMS concurrent sweep):并发清除阶段会清除对象。 由于整个过程中耗时最长的并发标记和并发清除过程收集器线程都可以与用户线程作,所以,从总体上来说,CMS收集器的内存回收过程是与用户线程起并发执的。

优点:

CMS是款优秀的收集器,它的主要优点在名字上已经体现出来了:并发收集、低停顿。

缺点:

CMS收集器对CPU资源非常敏感;

CMS收集器法处理浮动垃圾;

CMS收集器会产生大量空间碎

3.2 G1收集器(唯一一款全区域的垃圾回收器)

G1(Garbage First)垃圾回收器是在heap memory很的情况下,把heap划分为很多很多的 region块,然后并的对其进垃圾回收。

G1垃圾回收器在清除实例所占的内存空间后,还会做内存压缩。

年轻代垃圾收集

在G1垃圾收集器中,年轻代的垃圾回收过程使复制算法。把Eden区和Survivor区的对象复制到新的Survivor区域。 如下图:

年代垃收集:

对于年代上的垃圾收集,G1垃圾收集器也分为4个阶段,基本跟CMS垃圾收集器样,但略有不同:

初始标记(Initial Mark)阶段:同CMS垃圾收集器的Initial Mark阶段样,G1也需要暂停应程序的执,它会标记从根对象出发,在根对象的第层孩子节点中标记所有可达的对象。但是G1的垃圾收集器的Initial Mark阶段是跟minor gc一同发的。也就是说,在G1中,你不像在CMS那样,单独暂停应程序的执来运Initial Mark阶段,是在G1触发minor gc的时候并将年代上的Initial Mark给做了。

并发标记(Concurrent Mark)阶段:在这个阶段G1做的事情跟CMS样。但G1同时还多做了件事情,就是如果在Concurrent Mark阶段中,发现哪些Tenured region中对象的存活率很或者基本没有对象存活,那么G1就会在这个阶段将其回收掉,等到后的clean up阶段。这也是Garbage First名字的由来。同时,在该阶段,G1会计算每个 region的对象存活率,方便后的clean up阶段使 。

最终标记(CMS中的Remark阶段):在这个阶段G1做的事情跟CMS样, 但是采的算法不同,G1采用一种叫做SATB(snapshot-at-the-begining)的算法能够在Remark阶段更快的标记可达对象。

筛选回收(Clean up/Copy)阶段:在G1中,没有CMS中对应的Sweep阶段。相反,它有个Clean up/Copy阶段,在这个阶段中,G1会挑选出那些对象存活率低的region进回收,这个阶段也是和minor gc同发的,如下图所示:

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

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

相关文章

项目实战 - 贪吃蛇

目录 1. 基本功能 2. 技术要点 3. 环境 4. 效果演示 5. 控制台设置 6. Win32 API介绍 6.1 Win32 API 6.2 程序台控制(Console) 6.3 控制台屏幕上的坐标(COORD) 6.4 GetStdHandle 6.5 GetConsoleCursorInfo 6.5.1 CONSOLE_CURSOR_INFO 6.6 SetConsoleCursorInfo 6…

云原生架构概念

云原生架构概念 云原生架构(Cloud Native Architechtrue)作为一种现代软件开发的革新力量,正在逐渐改变企业构建、部署和管理应用程序的方式。它的核心优势在于支持微服务架构,使得应用程序能够分解为独立、松耦合的服务&#xf…

详解si5338 si53xx 设计使用及STM32 iic驱动设计

背景 在实际项目中经常使用si5338 si53xx,进行多路时钟的倍频以生成想要的时钟信号,但是针对si5338 si53xx设计使用缺少相关的资料,本文详解si5338 si53xx 设计使用及STM32 iic驱动设计,本文使用工程在项目中得到测试&#xff0c…

基于人体关节夹角的人体动作识别算法(代码+数据集)

为此本文提出了一个基于人体关节夹角的人体动作识别算法,主要做了以下工作: (1)提出了一个可解释性强,耗费算力较少且鲁棒性较高的基于人体关节夹角的人体动作序列的特征抽取方法。 (2)本文所使…

PyInstaller实战:打包Python应用并间接指定输出文件名

在深入探讨如何使用PyInstaller打包Python应用并指定输出文件名称的过程中,我们不仅可以了解基本的命令行操作和参数设置,还可以深入了解PyInstaller的工作机制、状态变化以及它在处理复杂Python项目时的优势。下面,我们将详细展开这一过程&a…

提升多跳问答中的语言模型知识编辑能力

人工智能咨询培训老师叶梓 转载标明出处 大模型在静态知识库的更新上存在局限,特别是在面对需要多步骤推理的多跳问题时,难以提供准确和最新的回答。为了解决这一问题,来自美国佐治亚大学、纽约大学、莱斯大学、北卡罗来纳州立大学等机构的研…

STM32F103C8----GPIO(跟着江科大学STM32)

一,GPIO简介 GPIO(General Purpose Input Output)通用输入输出口 可配置为8种输入输出模式 引脚电平:0V~3.3V(0V),部分引脚可容忍5V 输出模式下可控制端口输出高低电平,用以驱动…

idea2021安装教程与常见配置(可激活至2099年)

idea2021安装教程与常见配置(可激活至2099年) 下载 官网下载地址:https://www.jetbrains.com/zh-cn/idea/download/other.html 这里我们选择压缩包安装方式,选择2021.3 - Windows x64 ZIP Archive (zip),也可以选择exe安装方式 安装 解压缩安装方式 创建非中文目录D:\idea…

Win32绕过UAC弹窗获取管理员权限

在早些年写一些桌面软件时,需要管理员权限,但是又不想UAC弹窗,所以一般是直接将UAC的级别拉到最低,或者直接禁用UAC的相关功能。 什么是UAC(User Account Control) 用户帐户控制 (UAC) 是一项 Windows 安全功能,旨在保…

行走挖机多路比例阀控制放大器

挖掘机比例多路阀是挖掘机液压系统中的关键部件,它负责控制挖掘机各执行元件的运动方向、速度和力矩,从而影响挖掘机的作业效果。比例多路阀由多个阀块组成,其中比例控制阀由BEUEC比例放大器控制。每个阀块都有特定功能,如换向阀用…

昇腾大模型性能分析思路

性能分析 模型训练优化流程 我们根据性能问题的场景,按照单机和集群场景进行分类,再明确性能问题属于哪一类,明确好性能问题背景之后,才方便进行下一步问题的定位; 在明确问题背景后,参考性能分析工具介绍…

004、架构_详解(重点)

GoldenDB 分布式数据库框架 DN和RDB增加了备节点;引入新模块CM,且GTM、MDS、PM、CM都增加备节点;MDS、PM、CM、RDB被统一在了管理节点之中;GTM和MDS间多了一条连线,因为GTM的切换由MDS把控;初步系统架构mysqld:一般称为DB节点,负责单个节点的数据处理; dbproxy:一般…

FreeRTOS学习笔记—③RTOS内存管理篇(正在更新中)

二、RTOS的核心功能 RTOS的核心功能块主要分为任务管理、内核管理、时间管理以及通信管理4部分,框架图如下所示: (1)任务管理:负责管理和调度任务的执行,确保系统中的任务能够按照预期运行。 (…

【SpringBoot】使用Nacos服务注册发现与配置管理

前提:需要提前部署好nacos服务,这里可以参考我的文章:Windows下Nacos安装与配置 0. 版本信息 Spring Boot3.2.8Spring Cloud2023.0.1Spring Cloud alibaba2023.0.1.0nacos2.3.2本地安装的nacos2.3.0 Spring Boot、Spring Cloud、Spring Clo…

黑盒闪清 v2.9.9 体积小巧,简洁高效的手机清理神器

黑盒闪清APP是安卓手机上的一款优质文件管理器,拥有存储分析、文件分类、大文件扫描、空文件夹扫描等功能,应用无广告、无推送,完全免费使用,让你手机中的文件管理就跟在电脑上管理一样简单。 链接:https://pan.quark…

C语言学习笔记 Day16(文件管理--下)

Day16 内容梳理: C语言学习笔记 Day14(文件管理--上)-CSDN博客 C语言学习笔记 Day15(文件管理--中)-CSDN博客 目录 Chapter 10 文件操作 10.5 文件状态 10.6 文件的随机读写 fseek()、rewind() (1&…

对同一文件夹下所有excel表进行相同操作(数据填充、删除、合并)

背景引入:如图所示,笔者需要对数十个表格的银行日记账工作簿合并成一个工作簿,以便与本月银行流水进行核对。 为了方便银行日记账与银行流水进行核对,需要再每个村或小组的表格中,将村或小组的名称放在J列。 clear c…

Java | Leetcode Java题解之第392题判断子序列

题目&#xff1a; 题解&#xff1a; class Solution {public boolean isSubsequence(String s, String t) {int n s.length(), m t.length();int[][] f new int[m 1][26];for (int i 0; i < 26; i) {f[m][i] m;}for (int i m - 1; i > 0; i--) {for (int j 0; j…

9月4日C++作业

#include <iostream> #include <string> using namespace std; class Human {private:string name;int age;public:Human(){} //无参构造函数//有参构造函数Human(string i_name,int i_age):name(i_name),age(i_age){cout<<"调用了Human有参构…

一篇文章讲清楚什么是Spring AOP

目录 1、什么是代理&#xff1f; 1.1静态代理 1.2动态代理 2、什么是AOP&#xff1f; 3、AOP术语名词介绍 4、Spring AOP框架使用教程 5、Spring AOP框架细节讲解 1、什么是代理&#xff1f; 在讲解AOP之前&#xff0c;我们要先了解下什么是代理。 代理是二十四种设计…