【JVM】垃圾回收算法

2023-05-16

垃圾回收算法

文章目录

  • 垃圾回收算法
    • 标记-清除算法
    • 标记-复制算法
      • Appel式回收:
    • 标记整理算法
    • 混合使用

标记-清除算法

标记-清除算法是最早出席那也是最基础的垃圾收集算法,是1960年由Lisp之父John McCarthy所提出。

如它的名字 一样,算法分为“标记”和“清除”两个阶段:

  • 首先标记处所有需要回收的对象
  • 标记完成后,统一回收掉所有被标记的对象

之所以说它是最基础的收集算法,是因为后续的收集算法大多都是以标记-清除算法为基础,对其 缺点进行改进而得到的。

标记-清除算法缺点:

  • 执行效率不稳定,如果Java堆中包含对象对象,而且其中大部分都是需要回收的,这时必须进行大量标记和清除的动作,导致标记和清除两个过 程的执行效率都随对象数量增长而降低;
  • 内存空间的碎片化问题,标记、清除之后会产生大 量不连续的内存碎片,空间碎片太多可能会导致当以后在程序运行过程中需要分配较大对象时无法找 到足够的连续内存而不得不提前触发另一次垃圾收集动作。

在这里插入图片描述

标记-复制算法

标记-复制算法常被简称为复制算法。

为了解决标记-清除算法面对大量可回收对象时执行效率低 的问题,1969年Fenichel提出了一种称为“半区复制”(Semispace Copying)的垃圾收集算法,它将可用 内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着 的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。

如果内存中多数对象都是存 活的,这种算法将会产生大量的内存间复制的开销,但对于多数对象都是可回收的情况,算法需要复 制的就是占少数的存活对象,而且每次都是针对整个半区进行内存回收,分配内存时也就不用考虑有 空间碎片的复杂情况,只要移动堆顶指针,按顺序分配即可。这样实现简单,运行高效,不过其缺陷 也显而易见,这种复制回收算法的代价是将可用内存缩小为了原来的一半,空间浪费未免太多了一 点。

在这里插入图片描述

现在的商用Java虚拟机大多都优先采用了这种收集算法去回收新生代,IBM公司曾有一项专门研 究对新生代“朝生夕灭”的特点做了更量化的诠释——新生代中的对象有98%熬不过第一轮收集。因此 并不需要按照1∶1的比例来划分新生代的内存空间。

Appel式回收:

Appel式回收的具体做法是把新生代分为一块较大的Eden空间和两块较小的 Survivor空间,每次分配内存只使用Eden和其中一块Survivor。发生垃圾搜集时,将Eden和Survivor中仍 然存活的对象一次性复制到另外一块Survivor空间上,然后直接清理掉Eden和已用过的那块Survivor空间。HotSpot虚拟机默认Eden和Survivor的大小比例是8∶1。

也即每次新生代中可用内存空间为整个新 生代容量的90%(Eden的80%加上一个Survivor的10%),只有一个Survivor空间,即10%的新生代是会 被“浪费”的。当然,98%的对象可被回收仅仅是“普通场景”下测得的数据,任何人都没有办法百分百 保证每次回收都只有不多于10%的对象存活,因此Appel式回收还有一个充当罕见情况的“逃生门”的安 全设计,当Survivor空间不足以容纳一次Minor GC之后存活的对象时,就需要依赖其他内存区域(实际上大多就是老年代)进行分配担保(Handle Promotion)。

标记整理算法

标记-复制算法在对象存活率较高时就要进行较多的复制操作,效率将会降低。更关键的是,如果 不想浪费50%的空间,就需要有额外的空间进行分配担保,以应对被使用的内存中所有对象都100%存 活的极端情况,所以在老年代一般不能直接选用这种算法。

针对老年代对象的存亡特征,1974年Edward Lueders提出了另外一种有针对性的“标记-整 理”(Mark-Compact)算法,其中的标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可 回收对象进行清理,而是让所有存活的对象都向内存空间一端移动,然后直接清理掉边界以外的内 存,

标记-清除算法标记-整理算法的本质差异在于前者是一种非移动式的回收算法,而后者是移动 式的。是否移动回收后的存活对象是一项优缺点并存的风险决策

如果移动存活对象,尤其是在老年代这种每次回收都有大量对象存活区域,移动存活对象并更新 所有引用这些对象的地方将会是一种极为负重的操作,而且这种对象移动操作必须全程暂停用户应用 程序才能进行,这就更加让使用者不得不小心翼翼地权衡其弊端了,像这样的停顿被最初的虚拟机 设计者形象地描述为“Stop The World”

混合使用

虚拟机平时多数时间采用标记-清除算法,暂时容忍内存碎片的存在,知道内存空间的碎片化程度已经大到影响对象分配时,再采用标记整理算法手机一次,以获得规整的内存空间

CMS收集器面临空间碎片过多时采用的就是这种处理办法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【JVM】垃圾回收算法 的相关文章

  • linux线程切换怎么实现

    Linux线程切换的实现涉及到操作系统的调度 和线程上下文 的切换 线程上下文包括程序计数器 xff08 PC xff09 和寄存器值 xff0c 以及线程的堆栈和堆栈指针等 操作系统通过调度器决定哪个线程将获得CPU时间片来执行 当一个线
  • PID实时无线调参

    今天实现了PID参数的实时无线整定 xff0c 记录一下历程 1 将CRC h CRC c usart2 c usart2 h等文件添加到STM32工程中 如下图 xff1a 2 其中 xff0c CRC h CRC c用于数据包的校验 x
  • 海康威视工业相机SDK二次开发(VS+Opencv+QT+海康SDK+C++)(一)

    最近在做一个项目 xff0c 涉及到工业相机 xff0c 需要对其进行二次开发 相机方面选择了海康威视 xff0c 网上关于海康威视工业相机SDK的开发资料很少 xff0c 官方文档里面虽然写的是支持C 43 43 开发的 xff0c 但其
  • FFmpeg源码分析:写音视频帧av_write_frame()

    FFmpeg在libavformat模块提供音视频的muxer封装与demuxer解封装 其中muxer封装文件包括avformat write header av write frame 和av write trailer 本文主要探讨a
  • 海康威视工业相机SDK二次开发(VS+Opencv+QT+海康SDK+C++)(二)

    本文接上次的博客海康威视工业相机SDK二次开发 xff08 VS 43 Opencv 43 QT 43 海康SDK 43 C 43 43 xff09 xff08 一 xff09 xff0c 上个博客中并未用到QT xff0c 本文介绍项目内
  • 单目相机标定(使用Matlab)

    内容 一 单目视觉成像原理1 理想情况下相机成像模型1 1 世界坐标系 gt 相机坐标系1 2 相机坐标系 gt 图像坐标系1 3 图像坐标系 gt 像素坐标系1 4 总结 xff1a 世界坐标系 gt 像素坐标系 二 考虑畸变情况下相机成
  • 三菱PLC与上位机进行通讯

    三菱PLC与上位机串口通信 一 三菱Fx系列PLC编程口通讯协议地址算法1 DEVICE READ xff08 读出软设备状态值 xff09 2 DEVICE WRITE xff08 向PLC 软设备写入值 xff09 3 位设备强制置位
  • 关于相机的一些参数计算(靶面、视野等)

    1 靶面尺寸和芯片尺寸 比如我使用的是上面这个相机 xff0c 一直不懂1 1 8 39 是什么意思 span class token number 1 1 span 英寸 靶面尺寸为宽 span class token number 12
  • 面试问题总结——关于OpenCV

    整理了一下网上和我面试中遇到的关于OpenCV相关的问题 其中因为我的简历中有个项目用到了特征点检测相关的知识 xff0c 所以整理了SIFT SURF和FLANN 有些知识点也不深入 xff0c 对于写的不对的地方 xff0c 欢迎指正
  • 全排列(C++)

    递归法实现全排列 全排列就是指n个元素随机组合 xff0c 且不重复的所有排列方式 比如 1 xff0c 2 xff0c 3 xff0c 就有123 xff0c 132 xff0c 213 xff0c 231 xff0c 312 xff0c
  • 海康威视工业相机IP设置说明

    整理电脑文件时翻到的 xff0c 记录下来方便以后查阅 第一步 先修改本机IP步骤如下 xff1a 1 打开本地连接 2 点击属性 3 选择协议 gt gt 点击属性 4 选择使用下面IP地址 5 自己设置IP地址 xff0c 然后点击确认
  • 关于Aruco标记的理解并对其进行姿态估计的可视化显示

    目录 1 什么是ArUco标记1 1 Marker和字典 2 通过使用OpenCV生成ArUco标记图3 检测Aruco标记4 一些API的介绍getPredefinedDictionary drawMarker estimatePoseS
  • 关于手眼标定的误差计算

    之前做的眼在手上的手眼标定 xff0c 流程结束后 xff0c 会得到相机坐标系到机械臂末端坐标系的变换关系T cam2end 我一般直接量取机械臂末端到相机的直线距离来校对z轴方向的距离 xff0c 但只是做个估算 xff0c 并未进行精
  • 在Ubuntu 16.04上安装和配置VNC

    目录 1 VNC客户端配置2 VNC服务端配置2 1 本机远程连接服务器2 2 更新依赖包2 3 安装Xfce桌面环境2 4 安装tightvncserver 3 客户端VNC连接服务端4 关于VNC的一些指令5 设置VNC开机自启动 1
  • ffmpeg中av_find_best_stream()函数的使用

    av find best stream xff08 xff09 函数就是要获取音视频对应的stream index span class token macro property span class token directive has
  • ubuntu16.04+GTX1650 安装cuda,驱动会自动安装!+安装cudnn

    补充一句 只是做深度学习跑模型的话 xff0c 装完驱动后就可以了 xff0c 不需要额外按照NVIDIA官网的教程配置CUDA和CUDNN 我们的代码实际用到的是python环境下的包 比如我用anaconda配置环境 xff0c 直接在
  • ADRC线性自抗扰控制感应电机矢量控制调速Matlab Simulink仿真

    ADRC线性自抗扰控制感应电机矢量控制调速Matlab Simulink仿真 1 模型简介 模型为基于线性自抗扰控制 xff08 LADRC xff09 的感应 xff08 异步 xff09 电机矢量控制仿真 xff0c 采用Matlab
  • xubuntu16.04下安装向日葵并设置开机自启

    1 安装Sunlogin 下载 SunloginClient 11 0 1 44968 amd64 deb 解压后将SunloginClient 11 0 1 44968 amd64 deb拷贝到目标设备上 xff0c 终端运行 xff1a
  • xubuntu16.04下安装turboVNC并设置开机自启(TurboVNC + VirtualGL)

    关于TightVNC的安装和使用可参考 xff1a 在Ubuntu 16 04上安装和配置VNC 使用VNC过程中遇到的问题总结 为什么使用TurboVNC xff1f 虽然TightVNC可以进行远程桌面登录 xff0c 但如果运行有界面
  • xubuntu16.04安装x11vnc

    内容 1 安装x11vnc1 1 设置x11vnc的连接密码1 2 启动x11vnc服务 2 设置x11vnc开机自启动3 如何解决x11vnc远程连接后操作卡顿 xff0c cpu占用高 xff1f 1 安装x11vnc 有网络的情况下直

随机推荐

  • 服务器以root身份登录

    终端输入 su root xff0c 然后输入密码就行了
  • Linux系统下----make命令详解,地球人都在用的“编译工具”

    Make命令 1 功能介绍2 准备工作 写法和用法3 注意事项4 买家秀 5 其他 1 功能介绍 make命令是用来自动完成大批量源文件的编译工作的维护工具 xff1b 能够建立不同文件之间的依赖关系 xff1b 自动识别被修改的源文件并重
  • 小四轴实验:空心杯电机驱动

    单片机的io口带负载能力是较弱的 xff0c 即输出电流较小 xff0c 不能直接用io口驱动电机 事实上 xff0c 单片机的io口接大功率的LED灯都是比较困难的 因此我们需要外部电源供电 xff0c 通过驱动电路驱动电机转动 对于大型
  • 小四轴实验:四旋翼无人机飞行原理

    转速与飞行方式说明 参考博客 https blog csdn net qq 27270029 article details 79877022 https blog csdn net sinat 29315697 article detai
  • ST-LINK JLINK JTAG SWD接线图

  • PID参数起什么作用

    PID控制中有P I D三个参数 只有明白这三个参数的含义和作用才能完成控制器PID参数整定 让控制器到达最佳控制效果 昌晖仪表在本文给大家介绍PID控制中P I D参数的作用 比例作用 比例控制器实际上就是个放大倍数可调的放大器 要说明的
  • 如何在I2C通信中同时和多个从机通信

    对于不同地址的模块就不用多说了 xff0c 直接分别对其地址进行通信即可 那么若拿到相同地址的模块 xff0c 或者直接是相同的多个模块怎么办呢 xff1f 方法一 xff1a xff08 内置了两种地址的模块 xff09 对于内置了两种地
  • CUDA是什么-CUDA简介

    CPU GPU CPU CPU xff08 Central Processing Unit xff09 是一块超大规模的集成电路 xff0c 是一台计算机的运算核心 xff08 Core xff09 和控制核心 xff08 Control
  • 自动驾驶传感器评估 ——IMU惯性测量单元

    自动驾驶传感器评估 IMU惯性测量单元 前言 对于自动驾驶来说 xff0c 高精度定位必不可少 为了让自动驾驶系统更高频率的获取定位信息 xff0c 就必须引入更高频率的传感器 xff0c 这时就体现出了惯性测量单元 xff08 Inert
  • 洛谷:P1238 走迷宫(DFS)

    题目描述 有一个mn格的迷宫 表示有m行 n列 xff0c 其中有可走的也有不可走的 xff0c 如果用1表示可以走 xff0c 0表示不可以走 xff0c 文件读入这m n个数据和起始点 结束点 起始点和结束点都是用两个数据来描述的 xf
  • 通过ajax进行文件上传及回显并解决后台返回图片路径却不能直接显示问题

    1 选中图片立刻回显 前端代码 lt div class 61 34 row 34 id 61 34 uplodFilel 34 gt lt div class 61 34 col md 8 34 gt lt label gt 上传身份证正
  • STM32CubeMX配置串口

    配置串口 1 在Piont amp Configuration中的A gt Z找到USART1 xff1b 2 第一个选项Mode是用来设置串口模式或关闭串口 xff0c 第二个选项Hardware Flow Control用来开启硬件流控
  • postman汉化教程(历史老版本)

    目录 1 下载对应版本的postman 2 替换url中对应的版本号 3 下载postman对应版本的汉化包 4 打开postman文件位置 5 打开后寻找 app 9 12 2 resources 目录 然后将下载好的压缩包解压 6 重启
  • c++学习 :函数形参4种传递形式:(int a)(int &a)(int *a)(int *& a)

    c 43 43 学习 xff1a 函数形参4种传递形式 1 void func int para 2 void func int amp para 3 void func int pointer 4 void func int amp po
  • RTOS关于SysTickHandler()

    我们知道FREERTOS会自动装载PendSV Handler 和SVC Handler 函数 xff0c 这里我们希望自己对其从新定义 xff0c 故做如下处理 include 34 delay h 34 include 34 sys h
  • STM32 正点原子学习(个人学习)

    系统执行一般只设置一次优先级分组 设置好之后不再改变 xff0c 不然会导致混乱 抢占优先级先进行判断响应优先级后 xff0c 同级别抢占优先级但高级别的响应优先级也不能打断同级别抢占优先级低级别的响应优先级 系统中断优先级分组函数 xff
  • Spring AOP使用案例

    AOP 原理 代理模式 需求背景 返回前端的用户信息包含手机号等敏感内容 xff0c 并在系统上已经有大量接口 现拿到需求 xff0c 需要在返回前端的对象中 xff0c 找到手机号的属性并将手机号加密 现状 xff1a 分散在各处的接口中
  • 【JVM】说一下jvm运行时数据区域

    说一下jvm运行时数据区域 文章目录 说一下jvm运行时数据区域程序计数器栈本地方法栈堆方法区运行时常量池直接内存 本篇文章总结自 深入理解Java虚拟机 程序计数器 程序计数器是一块较小的内存空间 xff0c 它可以看作是当前线程所执行的
  • ffmpeg错误总结

    av err2str 在C 43 43 项目中 xff0c 使用FFmpeg中的av err2str函数时 xff0c 报错 解决 xff1a 调用该函数的文件开始加上以下代码 xff1a span class token keyword
  • 【JVM】垃圾回收算法

    垃圾回收算法 文章目录 垃圾回收算法标记 清除算法标记 复制算法Appel式回收 标记整理算法混合使用 标记 清除算法 标记 清除算法是最早出席那也是最基础的垃圾收集算法 xff0c 是1960年由Lisp之父John McCarthy所提