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

GC垃圾回收介绍及GC算法详解

目录

引言

GC的作用域

什么是垃圾回收?

常见的GC算法

1.引用计数法

2.复制算法

3.标记清除

4.标记整理

小总结

5.分代收集算法

ps:可达性分析算法?

可达性分析的作用

可达性分析与垃圾回收算法的关系

结论


引言

在编程世界中,内存管理是一个至关重要的话题。对于使用自动内存管理的语言(如Java、Python、Go等),垃圾回收(Garbage Collection, GC)机制是确保程序高效运行的关键。本文将介绍垃圾回收的基本概念,并详细讲解四种常见的垃圾回收算法。


GC的作用域

记住GC口诀: 分代收集算法

次数频繁Young区,次数较少Old区,基本不动Perm(永久区)区


什么是垃圾回收?

垃圾回收是一种自动内存管理机制,用于识别和释放不再被程序使用的内存。其主要目的是防止内存泄漏,减少程序员手动管理内存的负担,并提高程序的稳定性和性能。

先看下一个对象的历程:

JVM 在进行GC时,并非每次都对上面三个内存区域一起回收的,大部分时候回收的都是指新生代

因此GC按照回收的区域又分了两种类型,一种是普通的GC(minor GC),一种是全局GC (major GC or Full GC)

普通GC(轻GC):只针对新生代区域的GC

全局GC(重GC):针对老年代的GC,偶尔伴随对新生代的GC以及对永久代的GC


常见的GC算法

1.引用计数法

每个对象有一个引用计数器,当对象被引用一次则计数器加1,当对象引用失效一次,则计数器减1,对 于计数器为0的对象意味着是垃圾对象,可以被GC回收。


2.复制算法

年轻代中使用的是Minor GC,采用的就是复制算法

Minor GC 会把Eden中的所有活的对象都移到Survivor区域中,如果Survivor区中放不下,那么剩下的 活的对象就被移动到Old generation中,也就是说,一旦收集后,Eden就是变成空的了 当对象在Eden(包括一个Survivor区域,这里假设是From区域)出生后,在经过一次Minor GC后,如 果对象还存活,并且能够被另外一块Survivor区域所容纳 (上面已经假设为from区域,这里应为to区 域,即to区域有足够的内存空间来存储Eden 和 From 区域中存活的对象),则使用复制算法将这些仍然 还活着的对象复制到另外一块Survivor区域(即 to 区域)中,然后清理所使用过的Eden 以及Survivor 区域(即form区域),并且将这些对象的年龄设置为1,以后对象在Survivor区,每熬过一次Minor GC,就将这个对象的年龄 + 1,当这个对象的年龄达到某一个值的时候(默认是15岁,通过 XX:MaxTenuringThreshold 设定参数)这些对象就会成为老年代。

-XX:MaxTenuringThreshold  任期门槛=>设置对象在新生代中存活的次数

面试题:如何判断哪个是to区呢?一句话:谁空谁是to

工作原理

  • 将内存分为两个相等的区域:From空间和To空间。

  • 复制阶段:从From空间复制所有存活对象到To空间。

  • 清理阶段:清空From空间,然后交换From和To空间的角色。

优点

  • 简单高效,没有内存碎片问题。

缺点

  • 需要双倍内存空间,适用于存活对象较少的情况。


3.标记清除

说明:老年代一般是由标记清除或者是标记清除与标记整理的混合实现

什么是标记清除? 回收时,对需要存活的对象进行标记; 回收不是绿色的对象

当堆中的有效内存空间被耗尽的时候,就会停止整个程序(也被称为stop the world),然后进行两项 工作,第一项则是标记,第二项则是清除。

标记:从引用根节点开始标记所有被引用的对象,标记的过程其实就是遍历所有的GC Roots ,然后将所 有GC Roots 可达的对象,标记为存活的对象。

清除: 遍历整个堆,把未标记的对象清除。

缺点:这个算法需要暂停整个应用,会产生内存碎片。

工作原理

  • 标记阶段:从根对象(如全局变量、栈中的对象)出发,遍历所有可达对象,并标记它们为存活。

  • 清除阶段:遍历整个堆内存,释放未被标记的对象所占用的内存。

优点

  • 实现简单,适用于大多数场景。

缺点

  • 会产生内存碎片,可能导致后续内存分配效率降低。


4.标记整理

在整理压缩阶段,不再对标记的对象作回收,而是通过所有存活对象都像一端移动,然后直接清除边界 以外的内存。可以看到,标记的存活对象将会被整理,按照内存地址依次排列,而未被标记的内存会被 清理掉,如此一来,当我们需要给新对象分配内存时,JVM只需要持有一个内存的起始地址即可,这比 维护一个空闲列表显然少了许多开销。

标记、整理算法不仅可以弥补 标记、清除算法当中,内存区域分散的缺点,也消除了复制算法当中,内 存减半的高额代价;

工作原理

  • 标记阶段:与标记-清除算法相同,标记所有存活对象。

  • 整理阶段:将所有存活对象移动到内存的一端,然后清理边界以外的内存。

优点

  • 解决了内存碎片问题,提高了内存利用率。

缺点

  • 整理阶段需要移动对象,增加了时间开销。


小总结

内存效率:复制算法 > 标记清除算法 > 标记整理算法 (时间复杂度)

内存整齐度:复制算法 = 标记整理算法 > 标记清除算法

内存利用率:标记整理算法 = 标记清除算法 > 复制算法

可以看出,效率上来说,复制算法是当之无愧的老大,但是却浪费了太多内存,而为了尽量兼顾上面所提到的三个指标,标记整理算法相对来说更平滑一些 , 但是效率上依然不尽如人意,它比复制算法多了 一个标记的阶段,又比标记清除多了一个整理内存的过程

难道就没有一种最优算法吗?猜猜看,下面还有

答案 : 无,没有最好的算法,只有最合适的算法 。 -----------------> 分代收集算法

5.分代收集算法

工作原理

  • 基于对象的生命周期将内存分为不同的代(如年轻代和老年代)。

  • 年轻代:使用复制算法,因为大多数对象在年轻代中很快死亡。

  • 老年代:使用标记-清除或标记-整理算法,因为老年代中的对象存活时间较长。

优点

  • 针对不同生命周期的对象采用不同的回收策略,提高了回收效率。

缺点

  • 实现复杂,需要维护多个代的内存区域。


ps:可达性分析算法?

可达性分析算法(Reachability Analysis)本身并不是一个独立的垃圾回收算法,而是一种用于判断对象是否存活的技术。它是许多垃圾回收算法的基础,尤其是**标记-清除算法(Mark-Sweep)和标记-整理算法(Mark-Compact)**的核心部分。

可达性分析的作用

可达性分析通过从根对象(如全局变量、栈中的局部变量、静态变量等)出发,遍历所有被引用的对象,标记这些对象为“存活”。未被标记的对象则被认为是“垃圾”,可以被回收。

可达性分析与垃圾回收算法的关系

  • 标记-清除算法(Mark-Sweep)

    • 使用可达性分析来标记所有存活对象。

    • 在清除阶段,释放未被标记的对象的内存。

  • 标记-整理算法(Mark-Compact)

    • 同样使用可达性分析来标记存活对象。

    • 在整理阶段,将存活对象移动到内存的一端,然后清理剩余的内存。

  • 分代收集算法(Generational)

    • 在年轻代和老年代中,都可能使用可达性分析来判断对象的存活状态。

    • 年轻代通常使用复制算法,而老年代可能使用标记-清除或标记-整理算法。

  • 复制算法(Copying)

    • 虽然复制算法的主要特点是复制存活对象,但它也需要通过可达性分析来确定哪些对象是存活的。


结论

垃圾回收是现代编程语言中不可或缺的一部分,它通过自动管理内存,极大地简化了程序开发。不同的垃圾回收算法各有优缺点,适用于不同的应用场景。理解这些算法的原理和适用场景,有助于我们编写更高效、更稳定的程序。

相关文章:

GC垃圾回收介绍及GC算法详解

目录 引言 GC的作用域 什么是垃圾回收? 常见的GC算法 1.引用计数法 2.复制算法 3.标记清除 4.标记整理 小总结 5.分代收集算法 ps:可达性分析算法? 可达性分析的作用 可达性分析与垃圾回收算法的关系 结论 引言 在编程世界中,…...

2020 年英语(一)考研真题 笔记(更新中)

Section I Use of English(完型填空) 原题 Directions:Read the following text. Choose the best word (s) for each numbered blank and mark A, B, C or D on the ANSWER SHEET. (10 points) Even if families are less likely to si…...

【springboot】Spring 官方抛弃了 Java 8!新idea如何创建java8项目

解决idea至少创建jdk17项目 问题 idea现在只能创建最少jdk17,不能创建java8了吗?解决 问题 idea现在只能创建最少jdk17,不能创建java8了吗 我本来以为是 IDEA 版本更新导致的 Bug,开始还没在意。 直到我今天自己初始化项目时才发现&am…...

playbin之autoplug_factories源码剖析

一、autoplug_factories_cb /* Called when we must provide a list of factories to plug to pad with caps.* We first check if we have a sink that can handle the format and if we do, we* return NULL, to expose the pad. If we have no sink (or the sink does not…...

正浩创新内推:校招、社招EcoFlow社招内推码: FRQU1CY

EcoFlow社招内推码: FRQU1CY 投递链接: https://ecoflow.jobs.feishu.cn/s/Vo75bmlNr6c...

一文了解:部署 Deepseek 各版本的硬件要求

很多朋友在咨询关于 DeepSeek 模型部署所需硬件资源的需求,最近自己实践了一部分,部分信息是通过各渠道收集整理,so 仅供参考。 言归正转,大家都知道,DeepSeek 模型的性能在很大程度上取决于它运行的硬件。我们先看一下…...

有没有什么免费的AI工具可以帮忙做简单的ppt?

互联网各领域资料分享专区(不定期更新): Sheet 正文 1. 博思AIPPT 特点:专为中文用户设计,支持文本/文件导入生成PPT,内置海量模板和智能排版功能,涵盖商务、教育等多种场景。可一键优化布局、配色,并集成AI绘图功能(文生图/图生图)。适用场景:职场汇报、教育培训、商…...

python绘图之灰度图

灰度图(Gray Scale Image)是一种将图像中的像素值映射到灰度范围(通常是0到255)的图像表示方式。它在图像处理和计算机视觉中具有重要作用.本节学习使用python绘制灰度图 # 导入必要的库 import numpy as np import matplotlib.py…...

华为 VRP 系统简介配置SSH,TELNET远程登录

华为 VRP 系统简介&配置SSH/TELNET远程登录 1.华为 VRP 系统概述 1.1 什么是 VRP VRP(Versatile Routing Platform 华为数通设备操作系统)是华为公司数据通信产品的通用操作系统平台,从低端到核心的全系列路由器、以太网交换机、业务网…...

1.14 重叠因子:TRIMA三角移动平均线(Triangular Moving Average, TRIMA)概念与Python实战

目录 0. 本栏目因子汇总表1. 因子简述2. 因子计算逻辑3. 因子应用场景4. 因子优缺点5. 因子代码实现6. 因子取值范围及其含义7. 因子函数参数建议 0. 本栏目因子汇总表 【量海航行】 1. 因子简述 三角移动平均线(Triangular Moving Average, TRIMA)是一种特殊的加权移动平均…...

【tplink】校园网接路由器如何单独登录自己的账号,wan-lan和lan-lan区别

老式路由器TPLINK,接入校园网后一人登录,所有人都能通过连接此路由器上网,无法解决遂上网搜索,无果,幸而偶然看到一个帖子说要把信号源网线接入路由器lan口,开启新世界。 一、wan-lan,lan-lan区…...

PC 端连接安卓手机恢复各类数据:安装、操作步骤与实用指南

软件介绍 这款用于恢复安卓手机数据的软件,虽运行在 PC 端,却专为安卓手机数据恢复打造,使用时得用数据线把手机和电脑连接起来。它的功能相当强大,能帮你找回安卓手机里已删除的短信、联系人、通话记录、文档,还有照…...

【折线图 Line】——1

🌟 解锁数据可视化的魔法钥匙 —— pyecharts实战指南 🌟 在这个数据为王的时代,每一次点击、每一次交易、每一份报告背后都隐藏着无尽的故事与洞察。但你是否曾苦恼于如何将这些冰冷的数据转化为直观、吸引人的视觉盛宴? 🔥 欢迎来到《pyecharts图形绘制大师班》 �…...

SpringBoot 整合mongoDB并自定义连接池,实现多数据源配置

要想在同一个springboot项目中使用多个数据源,最主要是每个数据源都有自己的mongoTemplate和MongoDbFactory。mongoTemplate和MongoDbFactory是负责对数据源进行交互的并管理链接的。 spring提供了一个注解EnableMongoRepositories 用来注释在某些路径下的MongoRepo…...

TCP/IP的分层结构、各层的典型协议,以及与ISO七层模型的差别

1. TCP/IP的分层结构 TCP/IP模型是一个四层模型,主要用于网络通信的设计和实现。它的分层结构如下: (1) 应用层(Application Layer) 功能:提供应用程序之间的通信服务,处理特定的应用细节。 典型协议&am…...

FreeRTOS-中断管理

实验目的 创建一个队列及一个任务,按下按键 KEY1 触发中断,在中断服务函数里向队列里发送数据,任务则阻塞接 收队列数据。 实验代码 实验结果 这样就实现了,使用中断往队列的发送信息,用任务阻塞接收信息...

ShenNiusModularity项目源码学习(15:ShenNius.Admin.API项目分析)

ShenNius.Admin.Mvc项目是MVC模式的入口,ShenNius.Admin.Hosting项目是前后端分离模式的后台服务入口,这两个项目都依赖ShenNius.Admin.API项目,前者使用ShenniusAdminApiModule类注册服务及配置管道,而后者的webapi实现都在ShenN…...

Express + MongoDB 实现文件上传

使用 multer 中间件来处理文件上传,同时将文件的元数据存储到 MongoDB 中。 一、安装依赖 npm install multer 二、核心代码 // 定义文件模型const fileSchema new mongoose.Schema({originalname: String,mimetype: String,size: Number,path: String,});cons…...

计算机毕业设计SpringBoot+Vue.js作业管理系统(源码+文档+PPT+讲解)

温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...

Odoo免费开源CRM技术实战:从商机线索关联转化为售后工单的应用

文 / 开源智造 Odoo金牌服务 Odoo:功能强大且免费开源的CRM Odoo 引入了一种高效的客户支持管理方式,即将 CRM 线索转换为服务台工单。此功能确保销售和支持团队能够无缝协作,从而提升客户满意度并缩短问题解决时间。通过整合 CRM 模块与服…...

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

【kafka】Golang实现分布式Masscan任务调度系统

要求&#xff1a; 输出两个程序&#xff0c;一个命令行程序&#xff08;命令行参数用flag&#xff09;和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽&#xff0c;然后将消息推送到kafka里面。 服务端程序&#xff1a; 从kafka消费者接收…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业

6月9日&#xff0c;国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解&#xff0c;“超级…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

DingDing机器人群消息推送

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