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

JVM之【GC-垃圾清除算法】

Java虚拟机(JVM)中的垃圾收集算法主要分为以下几种:

  1. 标记-清除算法(Mark-Sweep)
  2. 复制算法(Copying)
  3. 标记-整理算法(Mark-Compact)
  4. 分代收集算法(Generational Collecting)
  5. G1垃圾收集器(Garbage-First)
  6. ZGC(Z Garbage Collector)
  7. Shenandoah垃圾收集器

1. 标记-清除算法(Mark-Sweep)

原理:

  • 标记阶段:从根对象开始,遍历整个对象图,标记所有被引用的对象。
  • 清除阶段:遍历整个堆,清除未被标记的对象,释放其内存。

优点:

  • 直观,简单,适用于任何对象图。

缺点:

  • 内存碎片化严重,因为清除阶段并不移动对象,导致堆中可能有大量不连续的可用空间,产生内存碎片。
  • 标记和清除阶段都需要扫描整个堆,效率较低。
  • GC的时候需要停止整个应用程序,用户体验不好
    在这里插入图片描述

2. 复制算法(Copying)

原理:

  • 将堆分为两个等大的区域,每次只使用其中一个。当活动对象达到一定比例时,将活动对象复制到另一个区域,然后清空当前区域。
  • 复制过程中保留活动对象,并保持对象的相对位置不变。

优点:

  • 没有内存碎片问题,因为每次都会在一个新的区域中重新排列对象。
  • 分配速度快,只需分配指针移动。

缺点:

  • 需要两倍的内存空间,因为要维持两个区域。
  • 对于存活率高的对象,复制成本高。
  • 只适用于存活对象少的情况/频繁消亡的情况(非常适合新生代)
    在这里插入图片描述

3. 标记-整理算法(Mark-Compact)

原理:

  • 标记阶段:与标记-清除算法相同。
  • 整理阶段:将所有存活的对象压缩到堆的一端,保持空间的连续性,然后清理边界以外的内存。

优点:

  • 消除内存碎片问题,因为对象都被压缩到一端,剩余空间连续。
  • 在整理阶段减少了内存分配的复杂度,消除了复制算法翻倍消耗内存的缺点。

缺点:

  • 整理阶段涉及大量对象移动,可能会导致较高的性能开销。
  • 效率其实不如复制算法,在对象移动后,其他地方引用了该对象的话,还需要同步修改对象的引用地址
    在这里插入图片描述

前面所有这些算法中,并没有一种算法可以完全替代其他算法,它们都具有自己独特的优势和特点。分代收集算法应运而生。

分代收集算法:是基于这样一个事实:不同的对象的生命周期是不一样的。因此,不同生命周期的对象可以采取不同的收集方式,以便提高回收效率。一般是把Java堆分为新生代和老年代,这样就可以根据各个年代的特点使用不同的回收算法,以提高垃圾回收的效率。

在Java程序运行的过程中,会产生大量的对象,其中有些对象是与业务信息相关,比如Http请求中的Session对象、线程、Socket连接,这类对象跟业务直接挂钩,因此生命周期比较长。但是还有一些对象,主要是程序运行过程中生成的临时变量,这些对象生命周期会比较短,比如:string对象,由于其不变类的特性,系统会产生大量的这些对象,有些对象甚至只用一次即可回收。

4. 分代收集算法(Generational Collecting)

详情请移步堆篇章
JVM之【运行时数据区2——堆】
原理:

  • 将堆划分为不同的代(一般为年轻代和老年代)。
  • 年轻代使用复制算法,老年代使用标记-清除或标记-整理算法。
  • 依据“弱分代假说”,大多数对象很快就会死亡。

优点:

  • 优化了垃圾收集的效率,因为年轻代对象存活率低,收集速度快。
  • 减少了老年代垃圾收集的频率。

缺点:

  • 需要复杂的调优工作,以确定代大小和收集策略。
  • 在年轻代和老年代之间的对象移动可能会产生额外的开销。

5. 分区收集算法/G1垃圾收集器(Garbage-First)

  • 一般来说,在相同条件下,堆空间越大,一次Gc时所需要的时间就越长,有关GC产生的停顿也越长。为了更好地控制GC产生的停顿时间,将一块大的内存区域分割成多个小块,根据目标的停顿时间,每次合理地回收若干个小区间,而不是整个堆空间,从而减少一次GC所产生的停顿。
  • 分代算法将按照对象的生命周期长短划分成两个部分,分区算法将整个堆空间划分成连续的不同小区间。
  • 每一个小区间都独立使用,独立回收。这种算法的好处是可以控制一次回收多少个小区间。

原理:

  • 将堆分为多个区域(regions),分别处理,优先回收垃圾最多的区域。
  • 结合了标记-清除和标记-整理算法,适用于大堆的垃圾收集。

优点:

  • 低暂停时间,适合大堆应用。
  • 可以并行和并发进行垃圾收集,提升性能。

缺点:

  • 相对较复杂的实现和调优。
  • 在某些情况下,性能可能不如其他收集器。

6.Shenandoah垃圾收集器

原理:

  • 以并发标记和并发整理为基础,最小化垃圾收集对应用线程的影响。
  • 使用并发压缩技术减少停顿时间。

优点:

  • 低停顿时间,适合延迟敏感应用。
  • 高效处理大堆内存。

缺点:

  • 复杂的实现和调优。
  • 性能可能受限于特定的硬件和JVM版本。

总结

不同垃圾收集算法和垃圾收集器各有优缺点,应根据具体应用需求和硬件环境选择合适的垃圾收集策略。标记-清除和复制算法比较基础,适用于小型或简单应用;分代收集算法适用于大多数常规应用;G1、Shenandoah更适合大内存、低延迟的高性能应用。

相关文章:

JVM之【GC-垃圾清除算法】

Java虚拟机(JVM)中的垃圾收集算法主要分为以下几种: 标记-清除算法(Mark-Sweep)复制算法(Copying)标记-整理算法(Mark-Compact)分代收集算法(Generational C…...

数据分析每周挑战——心衰患者特征数据集

这是一篇关于医学数据的数据分析,但是这个数据集数据不是很多。 背景描述 本数据集包含了多个与心力衰竭相关的特征,用于分析和预测患者心力衰竭发作的风险。数据集涵盖了从40岁到95岁不等年龄的患者群体,提供了广泛的生理和生活方式指标&a…...

单例模式(Java实现)

我的相关文章: JavaSE 学习记录-CSDN博客 多线程笔记-CSDN博客 单例模式(Java实现)-CSDN博客 JUC笔记-CSDN博客 注解与反射(Java,类加载机制,双亲委派机制)-CSDN博客 1. 懒汉式线程不安全 pu…...

24.面向对象六大原则

目录介绍 00.面向对象六大原则01.代码单一职责原则02.代码开放封闭原则03.代码里氏替换原则04.代码依赖倒置原则05.代码接口隔离原则06.代码迪米特原则00.面向对象六大原则 六大原则一句话介绍 单一职责原则:指一个类的功能要单一,不能包罗万象。开放封闭原则:指一个模块在扩…...

Vue3-shallowRef与shallowReactive

shallowRef 作用:创建一个响应式数据,但只对顶层属性进行响应式处理。 用法: let myVar shallowRef(initialValue);特点:只跟踪引用值的变化,不关心值内部的属性变化。 shallowReactive 作用:创建一个浅…...

CI/CD(基于ESP-IDF)

主要参考资料 B站乐鑫信息科技《【乐鑫全球开发者大会】DevCon23 #15 |通过 CI/CD 进行流水线开发》 pytest-embedded乐鑫文档: https://docs.espressif.com/projects/pytest-embedded/en/latest/api.html 目录 CI/CD简介乐鑫内部CI/CD测试GitLab CI/CDGitHub Actio…...

聚观早报 | 东风奕派eπ008将上市;苹果Vision Pro发布会

聚观早报每日整理最值得关注的行业重点事件,帮助大家及时了解最新行业动态,每日读报,就读聚观365资讯简报。 整理丨Cutie 6月3日消息 东风奕派eπ008将上市 苹果Vision Pro发布会 特斯拉Model 3高性能版开售 小米14推送全新澎湃OS系统 …...

k8s牛客面经篇

k8s的pod版块: k8s的网络版块: k8s的deployment版块: k8s的service版块: k8s的探针板块: k8s的控制调度板块: k8s的日志监控板块: k8s的流量转发板块: k8s的宏观版块:...

第9周 基于MinIO与OSS实现分布式与云存储

第9周 基于MinIO与OSS实现分布式与云存储 1. 基于mybatis-plus数据修改非空属性忽略更新2. 文件上传3. 分布式文件存储3.1 文件存储架构演变4. Minio docker安装5. 文件服务整合minio依赖minio API测试yml配置minio信息minio配置类业务:上传文件6. 云存储阿里OSS:要钱6.1 依赖6…...

【Linux内核-编程指南】

■ IPC组件 添加链接描述 ■ ■ ■ ■ ■...

Go 编程风格指南 - 最佳实践

Go 编程风格指南 - 最佳实践 原文:https://google.github.io/styleguide/go 概述 | 风格指南 | 风格决策 | 最佳实践 注意: 本文是 Google Go 风格 系列文档的一部分。本文档是 规范性(normative) 但不是强制规范(canonical),并且从属于Goo…...

awk的应用

步骤一:awk的基本用法 1)基本操作方法 格式1:awk [选项] [条件]{指令} 文件 格式2:前置指令 | awk [选项] [条件]{指令} 其中,print 是最常用的编辑指令;若有多条编辑指令,可用分号分隔。 …...

【网络原理】HTTP|认识请求“报头“|Host|Content-Length|Content-Type|UA|Referer|Cookie

目录 认识请求"报头"(header) Host Content-Length Content-Type User-Agent(简称UA) Referer 💡Cookie(最重要的一个header,开发&面试高频问题) 1.Cookie是啥? 2.Cookie怎么存的? …...

深入React Hoooks:从基础到自定义 Hooks

使用 useContext useContext 是另一个常用的 Hook,它可让我们在函数组件中轻松访问 React 的 context。如果你的应用程序依赖于一些全局状态,或者你希望避免将 props 一层一层地传递到子组件,context 很有用。你可以在父组件设置一个值&…...

9.7 Go语言入门(映射 Map)

Go语言入门(映射 Map) 目录六、映射 Map1. 声明和初始化映射1.1 使用 make 函数1.2 使用映射字面量 2. 映射的基本操作2.1 插入和更新元素2.2 访问元素2.3 检查键是否存在2.4 删除元素2.5 获取映射的长度 3. 遍历映射4. 映射的注意事项4.1 映射的零值4.2…...

过期视频怎么恢复?如何从手机、电脑和其他设备中恢复?

过期视频是指那些被误删、丢失或因系统升级等原因而无法正常访问的视频文件。这些视频可能包含了我们珍贵的回忆、重要的信息或者具有商业价值的内容。过期视频的恢复可以帮助我们找回失去的数据,减少损失,提高工作效率和生活质量。过期视频怎么恢复&…...

LeetCode刷题第2题

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。 请你将两个数相加,并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外,这两个数都不会以 0 …...

mysql执行拼接的sql语句

在MySQL中,可以使用 CONCAT() 函数来拼接SQL语句。但是,请注意,直接拼接SQL语句可能会导致SQL注入问题,因此应当使用参数化查询来避免这个问题。 以下是一个使用 CONCAT() 函数拼接SQL语句的例子: SET tableName us…...

使用 pm2 或 screen 等工具来管理和后台运行你的 Node.js 应用

使用 pm2 或 screen 等工具来管理和后台运行你的 Node.js 应用。 使用 pm2 pm2 是一个用于 Node.js 应用的进程管理工具,提供了守护进程、日志管理和应用重启等功能。 安装 pm2: npm install pm2 -g启动你的 Node.js 应用: pm2 start se…...

leetcode4 寻找两个正序数组的中位数

给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。 算法的时间复杂度应该为 O(log (mn)) 。 示例 1: 输入:nums1 [1,3], nums2 [2] 输出:2.00000 解释&a…...

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密

在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念&#xff0c;确保一个租户&#xff08;在这个系统中可能是一个公司或一个独立的客户&#xff09;的数据对其他租户是不可见的。在 RuoYi 框架&#xff08;您当前项目所使用的基础框架&#xff09;中&#xff0c;这通常是通过在数据表中增加一个…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述&#xff1a;指针 vs. 引用&#xff08;类比其他语言&#xff09;一、指针基础概念二、指针声明与初始化三、指针操作符1. &&#xff1a;取地址&#xff08;拿到内存地址&#xff09;2. *&#xff1a;解引用&#xff08;拿到值&#xff09; 四、空指针&am…...