四种垃圾收集算法详解(JVM)

news2024/11/14 15:02:41

一、标记清除

1、原理

从根集合节点进行扫描,标记出所有的存活对象,最后扫描整个内存空间并清除没有标记的对象(即死亡对象)

标记后 (黑色:可回收 | 灰色:存活对象 | 白色:未使用 ) 

 清除后

2、适用场景

  • 存活对象较多的情况下比较高效

  • 适用于年老代(即旧生代)

3、实现过程

  • 标记阶段

    • 标记阶段从root开始递归地给堆里所有被引用对象打上标记。标记算法一般是用深度或者广度搜索,深度搜索可以压缩内存使用量,所以一般用深度

  • 清除阶段

    • collector也会遍历整个堆,然后回收释放所有没有打标的内存对象

    • 清除阶段,通过变量 sweeping 遍历堆,具体来说就是从堆首地址 $heap_start 开始,按顺序一个个遍历对象的标志位

    • 遍历回收过程中,我们用free_list空闲链表来链接所有被回收的空闲内存块

4、优化过程

  • multi-size空闲链表优化分配速度,按照区块大小来分配链表

  • 延迟清理

5、优缺点

  • 优点

    • 实现简单,逻辑清晰。
    • 回收效率高,因为不需要移动存活对象。
  • 缺点

    • 会产生内存碎片,这可能导致在内存充足但碎片较多时,无法为新对象分配足够的连续内存空间。
    • 标记清除算法通常需要“Stop-the-World”,即暂停所有应用线程,以进行垃圾回收,这会影响应用的响应性能。

二、复制算法

1、原理

  • 将活着的内存空间分为两块,每次只使用其中一块,在垃圾回收时将正在使用的内存中的存活对象复制到未使用的内存块中,之后清除正在使用的内存块中的所有对象,交换两个内存的角色,最后完成垃圾回收

2、实现过程

内存划分

新生代内存被划分为Eden区和两个Survivor区(S0和S1)。默认情况下,Eden区和Survivor区的比例是8:1:1,即Eden区占80%,两个Survivor区各占10%。

对象分配

新创建的对象首先被分配在Eden区,如果Eden区满了,会触发一次Minor GC(Young GC)。

Minor GC过程

存活的对象(即还在被引用的对象)会被复制到其中一个Survivor区(S0或S1,假设当前使用的是S0)。清理Eden区和另一个Survivor区(S1)的内存空间。交换Survivor区的角色,即原本S0成为空闲区,原本S1成为下一次Minor GC的目标区。​​​​​​​内存使用效率:由于新生代中大部分对象都是朝生夕死的,因此复制算法在新生代中的实际效率是非常高的。只有少量存活对象需要被复制,大部分内存空间都可以直接被清理掉。

3、优缺点

  • 优点:

  • 没有标记和清除过程,实现简单,运行高效。

  • 复制过去以后保证空间的连续性,不会出现"碎片"问题。

  • 缺点:

  • 此算法的缺点也是很明显的,就是需要两倍的内存空间。

  • 对于G1这种分拆成大量region的GC,复制而不是移动,意味着GC需要维护region之间对象引用关系,不管是内存占用或者时间开销也不小

三、标记整理

1、原理

标记整理和标记清除的非常相似,但是标记整理的过程是这样的,首先是标记要清理的对象,然后将剩下所有存活的对象都移动到一端,然后直接清理端边界以外的内存。其实也就是标记-整理-清除算法,多了一个对内存的整理的过程。

图解:

回收前回收前 (黑色:可回收 | 灰色:存活对象 | 白色:未使用 ) 

回收后 

2、实现过程

标记整理算法主要分为两个阶段:标记阶段和整理阶段。

标记阶段:与标记清除算法相同,标记阶段会遍历整个堆内存,找出所有存活的对象(即被引用的对象),并给它们打上标记。

整理阶段:在标记阶段完成后,整理阶段会将所有存活的对象向一端移动(通常是向内存低地址方向移动),然后清理掉边界外的所有空间。这样,存活的对象就按照内存地址依次排列,从而消除了内存碎片

3、适用场景

JVM(Java Virtual Machine)中的标记整理(Mark-Compact)算法是垃圾回收(Garbage Collection, GC)的一种重要算法,它是对标记清除(Mark-Sweep)算法的改进,主要用于解决内存碎片问题

4、优缺点

算法优点

消除内存碎片:标记整理算法通过将所有存活对象移动到一端,并清理边界外的空间,从而有效消除了内存碎片,提高了内存空间的利用率。

提高内存分配效率:当需要给新对象分配内存时,JVM只需要维持一个内存的起始地址即可,这比维护一个空闲列表要简单得多,从而提高了内存分配的效率。

算法缺点

效率相对较低:与复制算法相比,标记整理算法在整理阶段需要移动存活的对象,这可能会导致一定的性能开销。尤其是在存活对象较多时,移动的开销会更加明显。

需要暂停用户线程:与大多数垃圾回收算法一样,标记整理算法在执行过程中也需要暂停用户线程(Stop-The-World, STW),以便对整个堆内存进行扫描和整理。这可能会影响应用程序的响应性能

四、增量算法

1、原理

增量算法的主要思想是将原本需要一次完成的垃圾回收过程拆分成多个较小的片段,这些片段可以在应用程序运行过程中交替执行,以减少单次垃圾回收所需的暂停时间

2、算法特点

减少STW时间:通过将垃圾回收过程拆分成多个较小的片段,增量算法可以显著减少单次垃圾回收所需的暂停时间,从而提高应用程序的响应性能。

交替执行:增量算法的各个片段可以在应用程序运行过程中交替执行,以实现垃圾回收与应用程序执行的并发。

逐步完成:增量算法通过逐步完成垃圾回收过程,可以在不中断应用程序执行的情况下,逐步释放内存空间

3、实现过程

增量算法的实现通常依赖于以下关键技术:

  1. 写屏障(Write Barrier):写屏障是一种用于在对象引用发生变化时执行特定操作的机制。在增量算法中,写屏障可以用于记录对象的引用变化,以便在后续的垃圾回收片段中处理这些变化。
  2. 读屏障(Read Barrier):读屏障用于在读取对象引用时执行特定操作。在增量算法中,读屏障可以用于确保在读取对象引用时能够正确地判断对象的存活状态。
  3. 增量标记(Incremental Marking):增量标记是增量算法中的核心部分,它负责在多个较小的片段中逐步完成对象的标记过程。通过增量标记,可以在不中断应用程序执行的情况下,逐步确定哪些对象是需要被回收的垃圾

4、优缺点

优势

  • 减少STW时间,提高应用程序的响应性能。
  • 允许垃圾回收与应用程序执行并发进行,提高系统吞吐量。

不足

  • 由于垃圾回收过程被拆分成多个片段交替执行,可能会增加垃圾回收的总时间。
  • 在处理对象引用变化时,需要引入额外的写屏障和读屏障机制,增加了系统的复杂性

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

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

相关文章

HarmonyOS鸿蒙- 跳转系统应用能力

一、通过弹窗点击设置跳转系统应用能力 1、 自定义弹窗效果图 2、 自定义弹窗代码 import { common, Want } from kit.AbilityKit; import { BusinessError } from kit.BasicServicesKit;export function alertDialog() {AlertDialog.show({title: ,message: 当前功能依赖定位…

算法力扣刷题记录 五十一【654.最大二叉树】

前言 二叉树篇,继续。 记录 五十一【654.最大二叉树】 一、题目阅读 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点,其值为 nums 中的最大值。递归地在最大值 左边 的 子数组前缀上 构建左子树。…

【Linux】安装PHP扩展-Swoole

说明 本文档是在centos7.6的环境下,安装PHP7.4之后,安装对应的PHP扩展Swoole。 一、swoole简述 Swoole 是一个为 PHP 设计的高性能的异步并行网络通信引擎,它以扩展(extension)的形式存在,极大地提升了 …

Linux--YUM仓库部署及NFS共享存储

目录 一、YUM仓库服务 1.1 YUM介绍 1.2 yum 常用的命令 1.3 YUM 源的提供方式 1.3.1 配置本地 yum 源仓库 1.3.2 配置 ftp 源 1.3.3 配置http服务源 二、NFS 共享存储 2.1 NFS基本概述 2.2 为什么使用 NFS 共享存储 2.3 NFS 应用场景 2.4 NFS 实现原理 2.5 NFS文件…

【python学习】爬虫中常使用的urllib和requests库的的背景、定义、特点、功能、代码示例以及两者的区别

引言 urllib是Python标准库中的一个模块,它提供了一系列用于操作URL的功能 requests是一个Python第三方库,由Kenneth Reitz创建,用于简化HTTP客户端的编程 一、urllib的定义 urllib可以操作url,主要分为以下几个子模块&#xff1…

Nginx详解(超级详细)

目录 Nginx简介 1. 为什么使用Nginx 2. 安装Nginx Nginx的核心功能 1. Nginx反向代理功能 2. Nginx的负载均衡 3 Nginx动静分离 Nginx简介 Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协…

深入Redis集群部署:从安装配置到测试验证的完整指南

🏡作者主页:点击! 🐧Linux基础知识(初学):点击! 🐧Linux高级管理防护和群集专栏:点击! 🔐Linux中firewalld防火墙:点击! ⏰️创作…

FastAPI 学习之路(六十)打造系统的日志输出

我们要搭建日志系统,可以使用loguru,很不错的一个开源日志系统 pip install loguru 我们在common创建log.py,使用方式也很简单 import os import timefrom loguru import logger# 日志的路径 log_path os.path.join(os.getcwd(), "log…

信息安全工程师题

物理隔离技术要求两台物理机物理上并不直连,只能进行间接的信息交换。所以防火墙不能实现网络的物理隔离Web应用防火墙可以防止SQL注入、xss攻击、恶意文件上传、远程命令执行、文件包含、恶意扫描拦截等;可以发现并拦截恶意的Web代码;可防止…

树形背包问题

一些题目给定了树形结构,在这个树形结构中选取一定数量的点或边(也可能是其他属性),使得某种与点权或者边权相关的花费最大或者最小。解决这类问题,一般要考虑使用树上背包。 树上背包,顾名思义&#xff0c…

JDK垃圾回收机制和垃圾回收算法

查看java相关信息 java -XX:PrintCommandLineFlags -version UseParallelGC 即 Parallel Scavenge Parallel Old,再查看详细信息 内存分配策略 1. 对象优先在 Eden 分配 大多数情况下,对象在新生代 Eden 区分配,当 Eden 区空间不够时,发…

STM32被拔网线 LWIP的TCP无法重连解决方案

目录 一、问题描述 二、项目构成 三、问题解决 1.问题代码 2.解决思路 3.核心代码: 四、完整代码 1.监测网口插入拔出任务 2.TCP任务 3.创建tcp任务 4.删除tcp任务 五、总结 一、问题描述 最近遇到一个问题,就是我的stm32设备作为tcp客户端…

c# listview控件调整标题显示顺序

右键点击listview,选择编辑列 修改DisplayIndex listview在成员位置点击上下箭头移动后,实际显示不会改变,因为DisplayIndex没有改变

Python 工程师对 3D 高斯溅射的介绍(第 1 部分)

从 Python 工程师的角度理解和编写 Gaussian Splatting 欢迎来到雲闪世界。2023 年初,来自法国蔚蓝海岸大学和马克斯普朗克信息研究所的作者发表了一篇题为“用于实时场渲染的 3D 高斯溅射”的论文。 该论文展示了实时神经渲染的重大进步,超越了 NeRF 等…

一文吃透,低代码是什么?盘点国内十大低代码平台,你用过哪个?

什么是低代码(Low Code)?低代码是怎么火的?国内十大低代码平台分别是谁?低代码项目开发流程是怎样的?低代码和无代码区别是啥?以及低代码的核心价值是什么?可以使用低代码开发平台创建哪些应用?…

el-cascader数据回显失败

el-cascader选中数据第一次回显正常,当选中数据改变再次回显时失败,呈现的还是上次的选中数据 如图 常用的方法this. n e x t T i c k ( ( ) > ) 跟 t h i s . nextTick(() > {})跟this. nextTick(()>)跟this.forceUpdate();强制刷新数据都无…

leetcode hot100_part30_二分查找

上次写博客已经一个月了,这段时间在做外卖项目,真的啥也没有就是个小玩具。 上次接触是在最长递增子序列的一个题解里,复习一下已经忘完了。如果我们在一个有序数组中进行查找某个target,一般肯定就是从小到大or从大到小遍历查找&…

js reduce 的别样用法

let mergedItems list.reduce((accumulator, currentItem) > {let existingItem accumulator.find((item) > item.manObject_name currentItem.manObject_name);if (existingItem) {existingItem.laborCostHand currentItem.laborCostHand; //劳务费existingItem.wor…

【网络】Socket编程

文章目录 正确理解端口号理解源IP地址和目的IP地址认识端口号端口号和进程ID 理解Socket网络字节序socket编程接口创建socket套接字bind绑定套接字listen建立监听accept接受连接connect建立连接sendto发送数据接收数据close关闭套接字 sockaddr结构体 正确理解端口号 理解源IP…

Windows 电脑部署 ollama3 并安装模型

Windows 电脑部署 ollama3 并安装模型 部署中为了尽可能减少对本地环境的污染,使用 Docker 安装! github: https://github.com/ollama/ollama 准备部署文件 version: 3.8services:ollama:volumes:- ./models:/root/.ollama # 将本地文件夹挂载到容器中…