JVM 的垃圾回收机制 GC

news2025/6/4 17:47:49

C/C++ 这样的编程语言中,申请内存的时候,是需要用完了,进行手动释放的

C 申请内存

1)局部变量(不需要手动释放)

2)全局变量(不需要手动释放)

3)动态申请 malloc(通过 free 进行释放的)

C++ 申请内存

1)局部变量

2)全局变量/静态变量

3)动态申请 new 通过 delete 进行释放

上面的释放操作,是很容易遗忘的(执行不到),就会导致内存泄漏

很多编程语言,引入了 垃圾回收机制

不需要程序员写代码手动释放,会有专门的逻辑,帮助自动释放

垃圾回收,大大的解放了程序员,提高了开发效率

Java, Python,Go,PHP,JS 大多数主流语言都包含了GC功能

为啥C/C++ 没有引入 GC 呢?

C++ 的设计核心理念,有两个(C++的红线)

1)和 C 兼容(C语言写的代码,用 C++ 的编译器可以正常编译运行的)

2)把性能发挥到极致

引入 GC 会影响性能,引入了额外的运行时开销

GC 会影响执行效率

触发 GC 的时候,可能会涉及到 STW 问题,(stop the world 世界都停止),(GC 这样的"扫地"操作,就需要其他工作线程"抬脚",抬脚就无法继续工作了)

1.GC 回收的内存区域是哪个部分呢?

JVM

程序计数器

元数据区

堆  => 主要是回收这个区域

2.GC 的目的是为了释放内存,是字节为单位"释放"的吗?

不是的,以"对象为单位"

按照对象为维度进行回收,更简单方便

如果是按照"字节维度",就可能针对每个对象都得描述出那部分需要回收,那部分不需要回收,比较麻烦了

堆上的内存 => new 的对象

3.如何回收?

1)找出垃圾,区分哪些对象是垃圾(后续代码不在使用)

2)释放这些垃圾对象的内存

如何"找出垃圾"(后续代码不在使用)

在 Java 使用对象,都是通过"引用"来进行的

使用对象,无非是使用的对象的属性/方法,都要通过 . 来进行 . 前面的部分就是指向对象的引用

如果一个对象以及没有任何引用指向它了,此时这个对象就注定无法使用了

判定一个对象是否是垃圾(抽象)

判定一个对象是是否有引用指向这个对象(具体,JVM 内部是有些办法可以做到的)

1.引用计数(Java 中没有使用,Python,PHP.. 采用的方案)

简单粗暴的方案

给每个对象都分配一个"计数器"

Python / PHP 等语言会搭配其他的算法机制,识别当前的引用是否构成循环引用

两个弊端

1)消耗额外的内存空间较大

        如果对象本身就很小(就 4 个字节)

        计数器占俩字节,相当于额外的内存空间多了 50%

2)循环引用问题(类似于死锁)

class Test {
    Test t;
}
Test a = new Test();
Test b = new Test();

class Test {
    Test t;
}
Test a = new Test();
Test b = new Test();

a.t = b;
b.t = a;

a = null;
b = null;

此时,这俩对象的引用计数是 1,不能释放.

但是,这俩对象却无法通过如何引用来访问到( A B 相互证明对方不是垃圾,实际上 AB 都是垃圾)

2.可达性分析(Java 的使用方案)

在 Java 代码中,每个"可访问的对象"一定是可以通过引用操作访问到的

JVM 安排专门的线程,负责上述的"扫描"的过程,会从一些特殊的引用开始扫描(GC roots)

1.栈上的局部变量(引用类型)

2.常量池里面指向的对象(final 修饰的,引用类型)

3.元数据区 (静态成员,引用类型)

这三组里面可能有很多变量,以这些变量为起点,尽可能的往里访问所有可能被访问到的对象

但凡是可以被访问到的对象,都"标记为可达"

JVM 又能知道所有的对象列表,去掉"标记为可达的",剩下的就是垃圾了

Node build() {
    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 = build();

此时通过 root 这个引用,是可以访问到这个树上的如何一个对象的

假设,写 root.right.right = null;

这样的代码会使 f 无法被访问到 (f 已经没有引用指向了)

假设,写 root.right = null

这样的代码会使 c 不可达,由于 f 必须依赖 c, f 也一起不可达

这种方法,不需要引入额外的内存空间,但是需要消耗较多的时间,进行上述的扫描过程,这些扫描过程中也是容易触发 STW 的(时间换了空间),这里也不会涉及到"循环引用"

如何释放垃圾(回收内存)

关于内存回收,涉及到几种算法

1.标记 - 清除

标记,就是可达性分析,找到垃圾的过程

清除,直接释放这部分的内存(相当于直接调用 free / delete 释放这个内存给操作系统)

存在内存碎片问题

总的空闲内存空间,是比较多的 (一共3MB),但是这些空闲的内存空间,不连续

在申请内存的时候,都是在申请连续的内存空间,当尝试申请 2MB 的内存时候,就会申请失败

2.复制算法,解决内存碎片

被红钩选择中的是"垃圾"

把不是垃圾的对象,复制到另外一侧,把整个空间都释放掉

很好的解决了内存碎片的问题

弊端

        1.内存浪费比较多

        2.如果存活的对象比较多/比较大,复制的开销是非常明显的

3.标记 - 整理

类似于顺序表删除元素 - 搬运元素

这个方案,能够解决内存碎片,也能避免负责算法的内存浪费,但是,搬运对象的成本也可能会比较高

4.分代回收(综合方案),把上述的几个方案,结合起来,扬长避短

整个堆空间,分成"新生代","老年代"

年龄:一个对象经过垃圾回收扫描线程的轮次

可达性分析中,JVM 会不停地使用线程扫描这些对象是否是垃圾,每隔一定的时间,就会扫描一次,如果一个对象扫描一次,不是垃圾,年龄就 + 1,一般来说年龄超过 15(可以配)的就进入老年代

对于年轻对象来说,是容易成为垃圾的,年老对象,着不容易成为垃圾

"要死早死了"

比如 C 语言,已经存在了50年了,还可以预见这个 C 语言还有很大的希望在活50年,和 C 语言同时期的语言,都死的差不多了

针对新新生代,老年代,不同的特点,就可以采用不同的方案了

刚创建的新对象,放到伊甸区

如果对象活过一轮 GC,进入幸存区(通过复杂算法)

新对象,大多数是生命周期非常低的"朝生夕死"

这俩幸存区,同一时刻使用一个(相当于是复杂算法,分出两个部分)

每次经过一轮 GC 都会淘汰掉幸存区中的一大部分对象,把存活的对象和伊甸区中新存活下来的对象,负责算法拷贝到另一个幸存区(新生代是非常适合负责算法的)

如果这个对象在新生代中存活多轮之后,就会进入老老年代

老年代的对象由于生命周期大概率是很长的,没有必要频繁扫描

如果这个对象是非常大的,不适合使用负责算法,直接进入老年代

老年代回收内存采取的是 标记 - 清除 / 标记 - 整理(取决于垃圾回收的具体算法实现了)

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

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

相关文章

路由器、网关和光猫三种设备有啥区别?

无论是家中Wi-Fi信号的覆盖,还是企业网络的高效运行,路由器、网关和光猫这些设备都扮演着不可或缺的角色。然而,对于大多数人来说,这三者的功能和区别却像一团迷雾,似懂非懂。你是否曾疑惑,为什么家里需要光…

vscode实时预览编辑markdown

vscode实时预览编辑markdown 点击vsode界面,实现快捷键如下: 按下快捷键 CtrlShiftV(Windows/Linux)或 CommandShiftV(Mac)即可在侧边栏打开 Markdown 预览。 效果如下:

2505软考高项第一、二批真题终极汇总

第一批2025.05综合题(75道选择题) 1、2025 年中央一号文件对进一步深化农村改革的各项任务作出全面部署。“推进农业科技力量协同攻关”的相关措施不包括()。 A.强化农业科研资源力量统筹,培育农业科技领军企业 B.发挥农业科研平台作用&…

云原生安全基础:Linux 文件权限管理详解

🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 在云原生环境中,Linux 文件权限管理是保障系统安全的核心技能之一。无论是容器化应用、微服务架构还是基础设施即代码(IaC&#xf…

[嵌入式实验]实验二:LED控制

一、实验目的 1.熟悉开发环境 2.控制LED灯 二、实验环境 硬件:STM32开发板、CMSIS-DAP调试工具 软件:ARM的IDE:Keil C51 三、实验内容 1.实验原理 (1)LED灯原理与点亮 LED即发光二极管,有电流通过…

6.4.2_3最短路径问题_Floyd算法

Floyd弗洛伊德 膜拜大佬,给大佬鞠躬鞠躬鞠躬。。。。。。。。。 Floyd算法 ----解决顶点间的最短路径: 过程: 如下: 初始化(没有中转点):2个邻接矩阵A和path,第一个是没有中转点的2个顶点之间的最短路径…

<PLC><socket><西门子>基于西门子S7-1200PLC,实现手机与PLC通讯(通过websocket转接)

前言 本系列是关于PLC相关的博文,包括PLC编程、PLC与上位机通讯、PLC与下位驱动、仪器仪表等通讯、PLC指令解析等相关内容。 PLC品牌包括但不限于西门子、三菱等国外品牌,汇川、信捷等国内品牌。 除了PLC为主要内容外,PLC相关元器件如触摸屏(HMI)、交换机等工控产品,如…

深度学习核心网络架构详解(续):从 Transformers 到生成模型

在上一篇文章中,我们详细介绍了卷积神经网络 (CNN)、循环神经网络 (RNN) 及其变体 LSTM 和 GRU。本文将继续探讨其他必须掌握的深度学习网络架构,包括 Transformers、生成对抗网络 (GAN)、自编码器 (Autoencoder) 以及强化学习基础。我们将深入讲解这些技…

AI智能混剪视频大模型开发方案:从文字到视频的自动化生成·优雅草卓伊凡

AI智能混剪视频大模型开发方案:从文字到视频的自动化生成优雅草卓伊凡 引言:AI视频创作的未来已来 近年来,随着多模态大模型(如Stable Diffusion、Sora、GPT-4)的爆发式发展,AI已经能够实现从文字生成图像…

allWebPlugin中间件VLC专用版之截图功能介绍

背景 VLC控件原有接口具有视频截图方法,即video对象的takeSnapshot方法,但是该方法返回的是一个IPicture对象,不适合在谷歌等现代浏览器上使用。因此,本人增加一个新的视频截图方法takeSnapshot2B64方法,直接将视频截图…

Scratch节日 | 六一儿童节

六一儿童节到啦!快来体验这款超简单又超好玩的 六一儿童节 小游戏吧!只需要一只鼠标,就能尽情释放你的创意,绘出属于你自己的缤纷世界! 🎮 玩法介绍 鼠标滑动:在屏幕上随意滑动鼠标&#xff0c…

深度解析:跨学科论文 +“概念迁移表” 模板写作全流程

跨学科论文速通!融合“概念迁移表”的写作导航模板 你的论文是否曾被导师皱眉评价为“四不像”?不同学科的术语在稿纸上打架,核心逻辑若隐若现? 别让心血沦为学术混搭的牺牲品。一张精心设计的 概念迁移表,能将两个看…

深度剖析Node.js的原理及事件方式

早些年就接触过Node.js,当时对于这个连接前后端框架就感到很特别。尤其是以独特的异步阻塞特性,重塑了了服务器端编程的范式。后来陆陆续续做了不少项目,通过实践对它或多或少增强了不少理解。今天,我试着将从将从原理层剖析其运行…

VScode-使用技巧-持续更新

一、Visual Studio Code - MACOS版本 复制当前行 shiftoption方向键⬇️ 同时复制多行 shiftoption 批量替换换行 在查找和替换面板中,你会看到一个 .∗ 图标(表示启用正则表达式)。确保这个选项被选中,因为我们需要使用正则…

主流 AI IDE 之一的 Windsurf 使用入门

一、Windsurf 的常见入门界面 以上是本次展示Windsurf版本信息。 1.1 个人配置中心 1.2 AI 助手快捷设置 1.3 使用额度查看页面 1.4 智能助手 Windsurf 编辑器中 AI 助手名称 :Cascade 。打开 Cascade 窗口,开始聊天就可以了。方框里有写和聊两种状态锁…

大数据量下的数据修复与回写Spark on Hive 的大数据量主键冲突排查:COUNT(DISTINCT) 的陷阱

背景与问题概述 这一周(2025-05-26-2026-05-30)我在搞数据拟合修复优化的任务,有大量的数据需要进行数据处理及回写,大概一个表一天一分区有五六千万数据,大约一百多列的字段。 具体是这样的我先取档案&#x…

历年南京理工大学计算机保研上机真题

2025南京理工大学计算机保研上机真题 2024南京理工大学计算机保研上机真题 2023南京理工大学计算机保研上机真题 在线测评链接:https://pgcode.cn/school 求阶乘 题目描述 给出一个数 n n n ( 1 ≤ n ≤ 13 ) (1 \leq n \leq 13) (1≤n≤13),求出它…

Web前端常用面试题,九年程序人生 工作总结,Web开发必看

前端编程,JavaScript 从无知到觉醒 做 Web 开发,离不开 HTML,CSS,JavaScript,尽管日常工作以后台开发为主,但接触的多了,慢慢地理解深入,从只会使用 JS 写函数,发展到使用…

Rk3568驱动开发_设备树点亮LED_11

代码&#xff1a; #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/slab.h> #include <linux/uaccess.h> #include <linux/io.h> #include <linux/cdev.h…

多功能文档处理工具推荐

软件介绍 今天为大家介绍一款功能强大的文档编辑工具坤Tools&#xff0c;这是一款在吾爱论坛广受好评的办公软件。 软件背景 坤Tools是由吾爱论坛用户分享的软件&#xff0c;在论坛软件榜单上长期位居前列&#xff0c;获得了用户的一致好评。 软件性质 这是一款完全离线、…