文章目录

  • 1. 标记-清除算法
  • 2. 复制算法
  • 3. 标记-整理算法
  • 总结与面试要点

在通过 可达性分析等算法识别出所有存活对象和垃圾对象后,垃圾收集器(GC:Garbage Collector)就需要执行回收操作来释放垃圾对象所占用的内存。以下是三种最基础、最经典的 垃圾回收算法

1. 标记-清除算法

标记-清除算法是最基础的收集算法,正如其名,它分为“标记”和“清除”两个阶段

  • 核心思想

    1. 标记阶段:首先,从GC Roots开始,遍历所有可达对象,并为这些存活的对象打上一个“标记”
    2. 清除阶段:然后,再次遍历整个堆内存。在此过程中,将所有未被标记的对象(即垃圾对象)所占用的内存直接回收
  • 过程

    请添加图片描述

    1. 初始状态:内存中对象杂乱无章地排列
    2. 标记后:所有从GC Roots可达的存活对象被标记
    3. 清除后:所有未被标记的垃圾对象被回收,其内存变为空闲
  • 优点

    • 实现简单:算法思想直观,易于实现
    • 空间利用率高:不需要额外的空间来进行回收操作,它是在原始堆上直接进行的
  • 缺点(非常重要)

    1. 执行效率不稳定:如果堆中包含大量对象,并且其中大部分是需要回收的,那么标记和清除两个过程的执行效率都会随着对象数量的增长而降低
    2. 内存碎片化:这是该算法最致命的缺点。清除之后,会产生大量不连续的内存碎片。虽然空闲内存的总量可能很大,但由于它们不连续,当程序需要分配一个较大的对象时,可能找不到一块足够大的连续内存空间,从而不得不提前触发下一次垃圾收集动作,甚至导致OutOfMemoryError

2. 复制算法

为了解决标记-清除算法带来的内存碎片化问题,复制算法应运而生

  • 核心思想
    它将可用的内存按容量划分为大小相等的两块,比如称为“From空间”和“To空间”。每次只使用其中的一块(From空间)。当这一块的内存用完了,就触发GC。GC会将From空间中所有仍然存活的对象,按顺序复制到另一块未使用的To空间中,然后一次性地清理掉整个From空间。之后,From空间和To空间的角色互换,下次GC时再从新的From空间复制到新的To空间

  • 过程

    请添加图片描述

    1. GC前:对象在From空间(Eden)分配,To空间(Survivor)是空的
  1. GC时:将From空间中的存活对象复制到To空间
  2. GC后:From空间被完全清空,所有存活对象都紧凑地排列在To空间的起始位置。然后From和To角色互换
  • 优点

    1. 无内存碎片:每次回收都是对整个半区进行内存整理,存活对象被复制到新空间后是连续存放的,不会产生碎片
    2. 实现简单,运行高效:在对象存活率较低的情况下,效率非常高。因为只需要复制少量存活对象,而不需要处理大量垃圾对象。分配内存时也极其简单,只需移动“堆顶指针”,按顺序分配即可
  • 缺点

    1. 空间代价高昂:算法的代价是将可用内存缩小为了原来的一半,空间浪费严重
    2. 对存活率敏感:如果对象存活率很高,复制操作的开销就会变得非常大,效率会急剧下降
  • 实际应用(重要)
    现代虚拟机(如HotSpot)的 新生代 普遍采用复制算法。因为研究表明,新生代中的对象98%以上是“朝生夕死”的,存活率极低。因此,在新生代使用复制算法,只需要付出少量存活对象的复制成本就可以完成收集

    细节优化:HotSpot虚拟机中的新生代并非简单的1:1划分。而是将内存分为一块较大的Eden空间和两块较小的Survivor空间(分别称为From和To,或S0和S1)。默认比例是Eden:S0:S1 = 8:1:1

    每次分配只使用Eden和其中一块Survivor。GC时,将Eden和正在使用的Survivor中的存活对象一次性复制到另一块空闲的Survivor空间上

    这样,平时可用的内存空间是整个新生代容量的90%(80% Eden + 10% Survivor),空间浪费问题得到了极大的缓解


3. 标记-整理算法

标记-整理算法结合了“标记-清除”和“复制”算法的优点,旨在解决前两者的弊端。它特别适用于对象存活率高的场景(如老年代)

  • 核心思想
    它的标记过程与“标记-清除”算法完全一样,但后续步骤不是直接对可回收对象进行清理,而是多了一个“整理”步骤

    1. 标记阶段:与标记-清除算法一致,从GC Roots开始标记所有存活对象
    2. 整理阶段:将所有被标记的存活对象,向内存空间的一端移动,并紧凑地排列。然后,直接清理掉边界以外的内存区域
  • 过程

    请添加图片描述

    1. 初始状态:内存中对象杂乱排列
    2. 标记后:存活对象被标记
    3. 整理后:所有存活对象被移动到内存的一端,形成连续的已用空间,另一端则成为连续的空闲空间
  • 优点

    • 无内存碎片:解决了标记-清除算法的碎片化问题,使得内存分配可以简单地使用“指针碰撞”技术
    • 无空间浪费:不像复制算法那样需要牺牲一半的内存空间
  • 缺点

    • 执行效率较低:标记和清除的效率问题依然存在。更重要的是,“整理”阶段需要移动大量对象,并且在移动后,还需要更新所有引用这些对象的指针,这是一个非常耗时的操作,需要暂停用户应用程序(STW: Stop The World)
  • 实际应用
    由于老年代(Old Generation)中的对象存活率高,且GC频率远低于新生代,因此不适合使用复制算法(复制开销大),而标记-清除算法的碎片问题又难以接受。所以,标记-整理算法通常用于老年代的垃圾收集


总结与面试要点

算法优点缺点适用场景
标记-清除实现简单,无空间开销效率不高,内存碎片化(致命)作为其他算法的基础,或在特定GC器中与其它算法结合使用
复制无内存碎片,效率高(存活率低时)空间浪费严重(可用内存减半),存活率高时效率低新生代
标记-整理无内存碎片,无空间浪费效率低,移动和更新引用开销大老年代

面试回答策略

  1. 清晰阐述三种算法的核心思想和执行步骤。画图辅助说明是很好的方式
  2. 精准说出每种算法的优缺点,特别是它们的“致命缺点”,这是面试官考察你是否理解深刻的关键
  3. 将理论与实践结合:一定要说明这些基础算法在现代JVM分代收集(Generational Collection)中的具体应用。即“分代假说”:
    • 新生代:对象存活率低 -> 采用复制算法
    • 老年代:对象存活率高 -> 采用标记-清除标记-整理算法(或它们的混合形式)

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JXD进步25.7.30

1.为啥是update,因为你if判断有问题。或者是你上来就给id赋值了。2. 这个是清空network历史3.断点位置打在这里:打在上面它进不来4.

Flutter开发实战之网络请求与数据处理

第6章:网络请求与数据处理 “数据是应用的血液,网络是连接世界的桥梁。” 在移动应用开发中,与服务器进行数据交互是必不可少的功能。无论是获取用户信息、提交表单数据,还是上传图片、下载文件,都离不开网络请求。本章将带你深入掌握Flutter中的网络编程技巧。 6.1 网络…

快速分页实现热点功能-索引和order by

需求:分页求出进三天的发布视频的权重热度 权重 / 衰减时间 衰减时间 当前时间 - 视频发布时间 小根堆来实现这个公式可以很好的利用半衰期来进行解决难点:如果一次性加载太多到springBoot服务器里面会造成堆内存占用过多,分页又有可能造成深分页问题,…

HAProxy(高可用性代理)

1 HAProxy 简介 HAProxy( High Availability Proxy)是一个高性能的负载均衡器和代理服务器,为基于 TCP 和 HTTP 的应用程序提供高可用性、负载平衡和代理,广泛应用于提高 web 应用程序的性能和可靠性。它支持多种协议&#xff0c…

Vulnhub靶场:ica1

一、信息收集nmap扫描一下IP。(扫不出来的可以看一下前面几篇找ip的步骤)下面给了框架的版本是9.2的,我们去kali里搜一下有没有已经公开的漏洞。searchsploit qdPM 9.2 locate 50176.txt more /usr/share/exploitdb/exploits/php/webapps/50…

【Dv3admin】ORM数据库无法查询的问题

Django 运行过程中,数据库连接的健康状态直接影响应用的稳定性和数据访问准确性。长时间空闲的数据库连接经常因外部机制被回收,进而引发数据查询异常和返回无效结果。 本文围绕 Django 中数据库连接长时间空闲导致的连接失效问题,介绍相关的…

使用 Flownex 对机械呼吸机进行建模

当患者无法独立呼吸时,机械呼吸机通过气管插管将富氧空气输送到患者的肺部。肺是敏感而复杂的器官,因此在无法忍受的压力和体积范围内提供空气,根据每分钟所需的呼吸次数计时,并适当加湿和加热。机械呼吸机的精确建模对于其安全有…

力扣刷题日常(7-8)

力扣刷题日常(7-8) 第7题: 整数反转(难度: 中等) 原题: 给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果. 如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0. 假设环境不允许存储 64 位整数(有符号或无符号).…

串口接收数据包(协议带帧头帧尾)的编程实现方法:1、数据包格式定义结构体2、使用队列进行数据接收、校验解包

这种带帧头帧尾的数据包处理流程可以简单概括为 “识别边界→提取有效数据→验证完整性” 三个核心步骤,具体操作如下:1. 数据包格式定义(先约定规则)首先明确一个 “合格数据包” 的结构,比如: 帧头&#…

JSON 对象封装教程

JSON 对象封装方法在 Java 中封装 JSON 对象通常使用第三方库&#xff0c;如 org.json、Gson 或 Jackson。以下是几种常见的方法&#xff1a;使用 org.json 库添加 Maven 依赖&#xff1a;<dependency><groupId>org.json</groupId><artifactId>json<…

【WRF-Chem】EDGAR 排放数据处理:分部门合并转化为二进制(Python全代码)

目录 process.py process_biofl.py process_fossil.py process_micro.py process_sector.py 参考 process.py 读取 EDGAR 排放数据库中 2000 至 2023 年间不同行业的甲烷(CH₄)排放数据,进行合并处理,并将总排放以二进制格式保存到文件中。 导入必要的库 import numpy as n…

【学习过程记录】【czsc】1、安装

文章目录 背景 安装 安装python 安装czsc 功能测试 附录 奇葩的报错 背景 详见: https://github.com/waditu/czsc 安装 安装python !重要!作者强调,python必须是大于等于3.8 为此呢,我也是花了一点时间装了一个python3.13。 安装czsc 关于czsc的安装呢,官方也是给出…

Python批量生成N天前的多word个文件,并根据excel统计数据,修改word模板,合并多个word文件

1&#xff0c;需求 根据word模板文件&#xff0c;生成多个带日期后缀的word文件根据excel-每日告警统计数量&#xff0c;逐个修改当日的文档2&#xff0c;实现 shell脚本&#xff1a;根据word模板文件&#xff0c;生成多个带日期后缀的word文件 #!/bin/bash # 生成近一年日期 …

基于uni-app的血糖血压刻度滑动控件

想要做一个基于uni-app的血糖血压刻度滑动控件&#xff0c;hbuilder市场没有好的&#xff0c;参照别人的写了一个。如图&#xff1a;源码&#xff0c;自己放入components里面。<!-- 刻度滑动选择 --> <template><view><view class"slide-title"…

C语言(02)——标准库函数大全(持续更新)

想要了解更多的C语言知识&#xff0c;可以订阅下面的专栏&#xff0c;里面也有很多品质好文&#xff1a; 打怪升级之路——C语言之路_ankleless的博客-CSDN博客 还在持续更新中&#xff0c;以下是学习过程中遇到的一些库函数&#xff08;排序不分先后&#xff09;&#xff1a…

永磁同步电机无速度算法--静态补偿电压模型Harnefors观测器

一、原理介绍本文基于Harnefors教授提出的静态补偿电压模型&#xff0c;可以实现带载零速启动、正反转切换等功能&#xff0c;原理清晰&#xff0c;实现简便。二、仿真模型在MATLAB/simulink里面验证所提算法&#xff0c;搭建仿真。采用和实验中一致的控制周期1e-4&#xff0c;…

[SKE]Python gmssl库的C绑定

Python gmssl库的C绑定 摘要:本文展示gmssl库的C绑定,并给出完整代码。将参考模型从Python脚本迁移到纯C代码中使用gmssl库(TongSuo项目,支持国密算法如SM4,同时兼容AES、DES、3DES、RSA等)。这样,UVM(SystemVerilog)可以通过DPI-C直接调用C函数,而无需嵌入Py…

4.方法的使用

方法是指一段具有独立功能的代码块&#xff0c;只有被调用时才会执行方法的主要作用体现在&#xff1a;代码组织&#xff1a;将原本挤在一起的臃肿代码按照功能进行分类管理例如&#xff1a;将用户注册的验证逻辑、数据库操作、结果返回等分离成不同方法提高复用性&#xff1a;…

day21-Excel文件解析

目录 1. 概述 2. Apache POI 3. XSSF解析Excel文件 3.1. 添加Jar包依赖 3.2. Workbook&#xff08;Excel文件&#xff09; 3.2.2. 加载&#xff08;解析&#xff09;Excel文件 3.3. Sheet &#xff08;工作簿&#xff09; 3.3.1. 创建工作簿 3.3.2. 获取工作簿 3.3.3.…

与 TRON (波场) 区块链进行交互的命令行工具 (CLI): tstroncli

源码仓库 一个基于 Node.js 和 TypeScript 构建的&#xff0c;用于与 TRON (波场) 区块链进行交互的命令行工具 (CLI)。 本项目旨在提供一个简单、可扩展的框架&#xff0c;让开发者可以轻松地通过命令行调用 TRON 的 HTTP API&#xff0c;实现查询链上信息、发送交易等操作。…