【JavaEE】JVM中垃圾回收机制详解

一.垃圾回收的基本概念

1.什么是垃圾回收机制.
  • JVM(Java虚拟机)垃圾回收机制是Java内存管理的重要组成部分,它负责自动回收程序中不再使用的对象所占用的内存空间。这样可以有效地防止内存泄漏和内存溢出问题,提高程序的稳定性和性能。简单来说就是不需要靠手动来进行内存的释放,而是依靠程序的自动发判定,某个内存是否会继续使用~~,如果内存后续不用了,就会自动释放掉了
2.垃圾回收机制的STW问题.
  • 垃圾回收的机制的有点很明显, 因此大部分的变成语言都引入了垃圾回收机制, 但是有优点必然会付出一定的代价,STW(stop the world ) 问题触发垃圾回收的时候,很可能会使当前程序的其他业务逻辑被暂停
3.垃圾回收机制的主要工作场所.
  • 是GC的主要战场, 其实这里说的垃圾回收, ==说的就是回收内存, 更准确的说是"回收对象".==每次垃圾回收的时候, 释放的若干个对象.(实际的单位都是对象)
    在这里插入图片描述

二.识别出垃圾

  • 识别出垃圾:就是判定这个对象后续是否要继续使用.(当然也有一个例外 ,匿名对象: new MyThread().start();但是这行代码执行完,对应的MyThread对象就会被当作垃圾~~
void func(){
	Test t = new Test();
	t.start(); 

在这里插入图片描述

  • 执行到完这个代码快的时候, 此时局部变量t就被释放了,此时再进一步讲, 上述的new Test()对象,也就没有引用指向它了. 此时,这个代码就无法访问使用这个对象,这个对象就是垃圾了.

  • 上述的情况是一个比较简单的垃圾回收的实例,但是如果有多个引用只想同一个对象,此时就不知道何时回收了.

解决方法一:引入计数.

  • 给每个对象安排一个额外的空间, 空间之中保存当前这个对象有几个引用. 这种思想方法,并没有在JVM中使用.但是广泛应用于其他主流语言的垃圾回收之中(Python,PHP)
  • 此时的垃圾回收机制会有专门的扫描线程, 去获得到当前每个对象的引用技术的情况, 当发现对象的引用计数为0的时候,说明这个对象就可以释放了.
引入计数存在的问题
问题一:消耗额外的空间存储.
  • 引入计数要给每个对象都安排一个计数器. (假设每个计数器按照两个字节计算),如果程序中对象数目很多,总的消耗空间也会非常多. 再举一个极端的例子—>如果每个对象体积比较小(假设每个对象4个字节),计数器消耗的空间占对象空间的一半.相当于你买了个100平米的房子,但是公摊面积就已经达到了50平米,这样计算非常的不划算.
问题二:循环引用问题
class Test{
	Test t;
}
Test a = new Test();
Test b = new Test();
a.t = b;
b.t = a;
a = null;
b = null;

在这里插入图片描述
此时代码就会出现问题, 这时的两个对象,引用计数都不是0~~不能被当作垃圾进行回收,但是这两个对象有无法使用,这里的情况非常类似于死锁.

解决方法二: 可达性分析(JVM就是用的这个)

  • 可达性分析的本质就是用时间换空间, 相比较于引用计数, 需要消耗更多额外的时间,但是总体来说,还是可以控制的,不会产生类似于循环引用的问题. 在写代码的时候会定义很多变量(比如栈上的局部变量/方法区的静态类型变量/常量池中引用的对象…) 就是可以从这些变量为起点出发,尝试进行遍历. 所谓的遍历就是会沿着这些变量中持有的引用类型的成员, 再进一步往下进行访问…所有能被访问的对象,自然就不是垃圾了,剩下的遍历一圈也访问不到的对象自然就是垃圾.
class Node{
	char val;
	Node left;
	Node right;
}
Node BuildTree(){
	Node a = new Node();
	Node b = new Node();
	Node c = new Node();
	Node d = new Node();
	Node e = new Node();
	Node f = new Node();
	Node g = new Node();
	a.left = b;
	a.right = c;
	b.left = d;
	b.right = e;
	e.left = g;
	c.right = f;
	return a;
}
Node root = buildTree();
  • 此时就会生成一个如下的图:
    在这里插入图片描述

  • JVM中存在扫描线程,会不停的尝试对代码中已有的变量进行遍历, 尽可能多的去访问对象. JVM自身知道一共有哪些对象,通过可达性分析的遍历, 把可达的对象都标记出来, 身下的就是不可达的(也就是GC回收的对象了)

举个例子

  • root.right.right = null : 此时的 f 就会被断开链接. 此时从root出发进行遍历, f 都是不可达的,此时就说明 f 的引用为零(为GC回收的对象)
  • root.right = null : 此时c节点就不可达了, 由于访问 f 必须经过 c ,因此 c 不可达,就会导致 c 和 f 都不可达了.此时 f 和 c 就都是垃圾了.

三.把标记为垃圾的对象的内存空间进行释放

释放方式一:标记–清除

什么是标记清除
  • 标记清除 本质上就是将标记为垃圾的对象进行清除(内存空间直接释放)
  • 此时就会产生碎片化的问题.
什么是碎片化问题
  • 碎片化问题就是本来变量存储在一块连续的内存空间之中,但是由于有些对象为垃圾,被直接释放了,此时就会造成, 内存空间的不连续性.
  • 危害由于内存空间的不连续,此时在向这一块内存空间中申请内存的时候,就会造成申请不成功的情况 . 造成这个情况的本质就是由于内存空间的不连续性, 造成即使这一块空间有很多空闲的空间,但是由于不连续,在申请空间的时候,就会造成申请不成功.

释放方式二:复制算法

什么是复制算法
  • 复制算法的核心就是不直接释放内存, 而是把不是垃圾的对象,复制到内存的另一半之中. 然后把左侧的空间释放掉. 能够规避内存碎片化的问题.
复制算法的弊端
    1. 总的内存空间变小的—>相当于你买了两个煎饼果子,买了一个, 扔了一个.
    1. 如果每次要复制的对象比较多, 此时的复制开销也就大了. (就意味着这一轮的GC大部分的对象不需要回收.).

释放方式三:标记-整理

什么是标记整理.
  • 标记整理;类似于顺序表删除中间元素的过程. 能够解决碎片化问题, 也不需要浪费过多的空间,但是搬运的成本非常大,会浪费大量的时间.

在这里插入图片描述
在这里插入图片描述

分代回收.

  • 由于上述的释放方式都存在一定的弊端, 因此JVM中没有直接使用上述的释放方案, 而是综合上述思想, 搞出了一个"综合性方案" -->分代回收.
什么是分代回收?
  • 分代回收 : 这里的分代可以理解为分年代(也可以理解为对象的年龄), JVM中有专门的线程负责周期性的扫描/释放. 一个对象如果被线程扫描了一次,并且是可达的,年龄就会加1(初始的年龄为0).

在这里插入图片描述

分代回收的基本流程.
    1. 当代码中new 出一个新的对象, 这个对象就是被创建在伊甸区的. 因此伊甸区就会有很多对象. 一个经验规律:伊甸区中的对象,大部分是活不过第一轮的GC的,这些对象都是"朝生夕死" ,生命周期非常短.
    1. 第一轮的GC扫描完成之后, 少数的伊甸区中的幸存的对象, 就会通过复制算法, 拷贝到的生存区. 后续的GC的扫描线程还会持续进行扫描,不仅要扫描伊甸区,也要扫描生存区的对象.
    1. 生存区的大部分对象也会在扫描中被标记为垃圾. 少数存活, 就会继续使用复制算法,拷贝到另一个生存区中. 往复循环,只要这个对象能够在生存区中继续存活,就会被复制算法继续拷贝到另一半的生存区之中. 每经历一轮GC的扫描. 对象的年龄都会+1.
    1. 如果这个对象在生存区中经历了若干次GC之后,仍然建在~~此时JVM就会认为,这个对象生命周期大概率很长,就会把这个对象从生存区拷贝到老年代.
    1. 老年代的对象,当然也要被GC扫描,但是扫描的频次就会大大降低了.
    1. 对象在老年代G了,此时JVM就会按照标记整理的方式,释放内存.

整个上述的过程概括下来就是,先放到伊甸区进行扫描,此时就会淘汰大部分对象,然后幸存下来的对象,就会被放到生存区/幸存区之中, 然后经过很多伦的GC仍然没有被淘汰此时,就会进入老年代,进入老年代之后,扫描的概率也就小了.这样能够提高效率.

举一个具体的例子:
伊甸区:就相当于一个公司在招聘,在第一轮的笔试之中就会刷下来一大批人,.
生存区/幸存区: 相当于进入了面试,但要面试好几轮.
老年代: 相当于成为了正式员工, 此时淘汰的概率就比较低了.

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

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

相关文章

电脑死机问题排查

情况描述:2024年6月2日下午16:04分电脑突然花屏死机,此情况之前遇到过三次,认为是腾讯会议录屏和系统自带录屏软件冲突导致。 报错信息:应用程序-特定 权限设置并未向在应用程序容器 不可用 SID (不可用)中运行的地址…

GPT-4o有点坑

GPT-4o有点坑 0. 前言1. GPT-4o简介2. GPT-4o带来的好处2.1 可以上传图片和文件2.2 更丰富的功能以及插件 3. "坑"的地方3.1 使用时间短3.2 GPT-4o变懒了 4. 总结 0. 前言 原本不想对GPT-4o的内容来进行评论的,但是看了相关的评论一直在说:技…

全国水系数据(更新到2024年5月)

上海市水系数据地图可视化 水系数据线图层(小河/溪流、江/河、运河、下水道/排水管) 水系数据面数据(水域、水库、河岸、湿地) 水系数据字段说明 可视化预览 北京市水系可视化 上海市水系可视化 广州市水系可视化 深圳市水系可视化…

Gin的快速入门和搭建

文章目录 Go的工程工程架构技术选型 Gin入门 Go的工程 基于Go生态,构建一个支持内容管理,内容加工、内容分发的内容库系统。 内容管理:增删改查内容加工:例如内容审核、推荐等内容分发:将内容可以推到不同的业务线 …

用例篇03

正交表 因素:存在的条件 水平:因素的取值 最简单的正交表:L4(2) 应用 allpairs 来实现正交表。 步骤: 1.根据需求找出因素和水平 2.将因素和水平写入到excel表格中(表格不需要保存)(推荐用…

集成学习算法笔记

一、引言 在机器学习和数据分析领域,集成学习算法因其能够显著提高模型预测性能而备受关注。然而,任何算法在应用过程中都不可避免地会遇到一些挑战和问题,集成学习算法也不例外。其中,最为常见且关键的两大问题便是欠拟合&#…

软考高级系统规划与管理师适合什么人考?有什么优势?

系统规划与管理师适合什么人考? 适合以下几类人群: 1. 信息技术服务规划人员:从事信息技术服务规划工作,负责制定和优化IT服务规划的人 2. 信息系统运行维护管理人员:负责信息系统日常运行维护、确保系统稳定性和可…

【Pr剪辑】01新建项目起步

【Pr学习】01新建项目起步 1、新建项目2.序列设置2.1新建序列2.2序列参数讲解2.3自定义设置 3.PR窗口认识3.1 项目窗口3.2 源窗口2.4 保存面板 4.剪辑导入4.1 素材导入4.2 视图切换4.3 时间轴4.4轨道工具4.5 节目窗口素材导入 5.基础操作5.1 取消视频音频链接5.2 单独渲染&…

网络监听技术

网络监听技术 网络监听概述网络监听环境 流量劫持网络环境共享式网络监听原理交换式网络监听交换机的工作方式交换网络监听:交换机集线器交换网络监听:端口镜像交换网络监听:MAC洪泛交换网络监听:MAC洪泛交换网络监听:…

OpenMV学习笔记3——画图函数汇总

画图,即在摄像头对应位置画出图形,对于需要反馈信息的程序来说很直观。就如上一篇文章颜色识别当中的例子一样,我们在识别出的色块上画出矩形方框,并在中间标出十字,可以直观的看到OpenMV现在识别出的色块。 目录 一…

《论文阅读》通过顺序不敏感的表示正则化实现稳健的个性化对话生成 ACL 2023

《论文阅读》通过顺序不敏感的表示正则化实现稳健的个性化对话生成 ACL 2023 前言 相关个性化生成论文推荐简介问题定义方法损失函数实验结果 前言 亲身阅读感受分享,细节画图解释,再也不用担心看不懂论文啦~ 无抄袭,无复制,纯手…

Least-Squares Rigid Motion Using SVD——文献精读(使用 SVD 方法求解 ICP 问题)

一、文章信息与摘要 文章标题:Least-Squares Rigid Motion Using SVD(使用奇异值分解的最小二乘刚性运动) 说明本文的核心目标:计算对齐两组对应点的最佳拟合刚性变换的步骤 二、问题描述 假设P{p1,p2,...,pn}和Q{q1,q2,...,qn…

以sqlilabs靶场为例,讲解SQL注入攻击原理【25-31关】

【Less-25】 首先分析源码 发现把 SQL语句中的 or、and 替换成了空格,这就导致无法使用之前的sql注入方式。 解决方案:用 && 代替 and , 用 || 代替 or , 而且&在url中有特殊含义,如果直接使用会有问题&a…

电磁兼容(EMC):BUCK变换器基本原理及传导辐射分析设计

目录 1. BUCK电路拓扑及原理 2. Buck拓扑电路电磁场分析 3.总结 开关电源替代线性电源,解决了效率和体积问题,但也带来了新的EMI问题。开关电源也是产品内部的强辐射源之一,基于透过现象看本质,将复杂问题简单化,本…

2024年06月在线IDE流行度最新排名

点击查看最新在线IDE流行度最新排名(每月更新) 2024年06月在线IDE流行度最新排名 TOP 在线IDE排名是通过分析在线ide名称在谷歌上被搜索的频率而创建的 在线IDE被搜索的次数越多,人们就会认为它越受欢迎。原始数据来自谷歌Trends 如果您相…

JAVA流程控制--For循环

1.虽然所有循环都可以用while或do...while表示,但Java提供了另外一种语句——for循环,使一些循环结构变得简单 2.for循环语句是支持迭代的一种通用结构,是最有效,最灵活的循环,结构 3.for循环执行的次数是在…

快速排序(排序中篇)

1.快速排序的概念及实现 2.快速排序的时间复杂度 3.优化快速排序 4.关于快速排序的细节 5.总代码 1.快速排序的概念及实现 1.1快速排序的概念 快速排序的单趟是选一个基准值,然后遍历数组的内容把比基准值大的放右边,比基准值小的放在左边&#xf…

编译原理【第四+七章】

考试题 1、简述语法制导翻译的基本思想 将语法分析和语义分析结合起来,通过语法规则驱动语义动作执行,用于将源程序翻译成目标代码或中间代码。 通过使用属性和语义动作,编译器可以在语法分析的同时生成目标代码或中间代码,实现…

网络原理——TCP/IP--数据链路层,DNS

T04BF 👋专栏: 算法|JAVA|MySQL|C语言 🫵 今天你敲代码了吗 目录 数量链路层目的地址和原地址类型校验和 DNS 数量链路层 主要的协议是以太网协议.一个横跨数据链路层和 物理层的协议,既包含了数据链路层的内容, 也包含了⼀些物理层的内容 我们来了解一…

STM32作业实现(五)温湿度传感器dht11

目录 STM32作业设计 STM32作业实现(一)串口通信 STM32作业实现(二)串口控制led STM32作业实现(三)串口控制有源蜂鸣器 STM32作业实现(四)光敏传感器 STM32作业实现(五)温湿度传感器dht11 STM32作业实现(六)闪存保存数据 STM32作业实现(七)OLED显示数据 STM32作业实现(八)触摸按…