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

jvm的垃圾回收算法有哪些

        jvm的垃圾回收算法有标记-清除、复制、标记-整理、分代回收算法,它们分别有不同的实现:

一、标记-清除算法

        利用可达性分析算法分析之后,将未被标记的对象[即不可达对象]清除,以便回收它们所占用的内存。

缺点:

        1、需要对内存进行两次遍历,一次遍历标记,一次遍历清除,效率较低;

        2、这种算法会造成大量的内存碎片,以至于出现当我们需要一片连续的大的内存空间去存储对象的时候无法找到合适的内存。

        CMS收集器就是用的标记-清除算法,CMS为了解决碎片式内存提供了内存合并整理的功能,但是这个功能的执行会导致用户线程暂停,会延长STW,导致程序性能下降。

二、复制算法:

        为了解决清除算法的内存碎片问题,复制算法将内存一分为二,每次只使用一半的内存去存储对象,当这一半内存不够用的时候触发gc,将存活下来的对象移到另外一半内存,然后将当前这一半内存清空,以便在下一次gc的时候使用。

        复制算法是没有标记过程的,它在可达性分析的过程中将存活的对象直接复制到另一半内存。而标记过程是为了找出未被标记的对象来进行清除。

缺点

        每次只能使用一半内存,内存使用率低,gc频繁。

改进

        在新生代中,因为大部分的对象都是朝生夕死,每次gc存活下来的对象占比很少,所以将新生代按照8:1:1的比例划分为Eden、survivor from、survivor to三个区,每次minor gc时,都是将eden和一个survivor区存活下来的对象复制到另外一个survivor区,然后清空eden和对应的survivor区。虽然我们其实是无法保证每次minor gc过后存活下来的对象占比永远低于10%,但是有老年代为新生代做内存兜底,当存活下来的对象在另一个survivor区保存不下时,将这些对象转移到老年代。

三、标记-整理算法 

         先对对象进行标记,然后将存活下来的对象向内存的一端移动,然后回收不再存活的对象所占用的内存。标记整理算法是针对于老年代提出来的算法,因为老年代的大部分对象都是经过了很多次gc之后仍然存活的对象,这些对象生存率高,如果对它们使用复制算法的话,就会造成一次次的复制而浪费时间。

四、分代收集算法 

        因为新生代和老年代的对象有着不同的特点,新生代存放的是大部分的新创建的对象,这些对象大部分都是朝生夕死,因此每次minor gc都会有大量的对象被回收;而老年代的对象是经历了多次gc依然存活下来的对象,老年代中的对象存活率高。所以我们不适合将新生代和老年代的对象一起gc,新生代和老年代适合不同的gc算法,并且适合在不同的时机去触发gc。新生代使用复制算法,老年代使用标记整理或清除算法。现在的商用的虚拟机都是使用分代收集。 


 

CMS和G1 

        cms收集器只回收老年代,使用标记-清除算法;G1既回收新生代又回收老年代,使用标记-整理算法。

        CMS因为其使用的是标记-清除算法,所以会有个严重问题就是在gc之后产生大量的内存碎片,当我们无法找到一块儿足够大的连续内存去存储对象的时候,就不得不再一次触发gc。

        G1打破了原有的对于堆的分代概念,将堆分为一个个大小相等的region,并且提供了可预测的停顿时间模型,使得我们可以去设置在一定的时长内所期望的停顿时间,在执行gc的时候,会将region按照回收价值和回收耗时进行排序,依据我们所设置的期望停顿时间去制定一个回收方案,回收部分region。

        G1的优势很明显,它无需和其他的收集器配合,自己便可以回收新生代和老年代;它支持可预期的停顿时间,提高了gc的效率。

垃圾回收的触发时机 

新生代垃圾回收触发时机

        当 eden 区内存无法为一个新对象分配内存时,就会触发 Minor GC

老年代垃圾回收触发时机:

        1、如果没有设置-XX:+UseCMSInitiatingOccupancyOnly,虚拟机会根据收集的数据决定是否触发(建议线上环境带上这个参数,不然会加大问题排查的难度)。
        2、老年代使用率达到阈值 CMSInitiatingOccupancyFraction,默认92%。
        3、永久代的使用率达到阈值 CMSInitiatingPermOccupancyFraction,默认92%,前提是开启 CMSClassUnloadingEnabled
        4、新生代的晋升担保失败。老年代没有足够的空间来容纳全部的新生代对象或历史平均晋升到老年代的对象,如果不够的话,就提早进行一次老年代的回收,防止下次进行YGC的时候发生晋升失败。

老年代空间分配担保规则

        在执行任何一次Minor GC之前,JVM会先检查一下老年代的可用内存空间,是否大于新生代所有对象的总大小。因为在极端的情况下,可能新生代Minor GC过后,所有对象都存活下来了,并且所有对象全部要晋升到老年代,老年代得有足够的空间去存储它们。

        假如Minor GC之前,发现老年代的可用内存已经小于了新生代的全部对象大小了,就会看一下“-XX:-HandlePromotionFailure”的参数是否设置了如果有这个参数,那么就会继续尝试进行下一步判断。

        下一步判断,就是看看老年代的内存大小,是否大于之前每一次Minor GC后进入老年代的对象的平均大小。

        举个例子,之前每次Minor GC后,平均都有10MB左右的对象会进入老年代,那么此时老年代可用内存大于10MB。

        这就说明,很可能这次Minor GC过后也是差不多10MB左右的对象会进入老年代,此时老年代空间是够的,

        如果上面那个步骤判断失败了,或者是“-XX:-HandlePromotionFailure”参数没设置,此时就会直接触发一次“Full GC”,就是对老年代进行垃圾回收,尽量腾出来一些内存空间,然后再执行Minor GC。

        如果上面两个步骤都判断成功了,那么就是说可以冒点风险尝试一下Minor GC。此时进行Minor GC有几种可能。

        第一种可能,Minor GC过后,剩余的存活对象的大小,是小于Survivor区的大小的,那么此时存活对象进入Survivor区域即可。

        第二种可能,Minor GC过后,剩余的存活对象的大小,是大于 Survivor区域的大小,但是是小于老年代可用内存大小的,此时就直接进入老年代即可。

        第三种可能,很不幸,Minor GC过后,剩余的存活对象的大小,大于了Survivor区域的大小,也大于了老年代可用内存的大小。此时老年代都放不下这些存活对象了,就会发生“Handle Promotion Failure”的情况,这个时候就会触发一次“Full GC”。

        Full GC就是对老年代进行垃圾回收,同时也一般会对新生代进行垃圾回收。因为这个时候必须得把老年代里的没人引用的对象给回收掉,然后才可能让Minor GC过后剩余的存活对象进入老年代里面。如果要是Full GC过后,老年代还是没有足够的空间存放Minor GC过后的剩余存活对象,那么此时就会导致所谓的“OOM”内存溢出了。因为内存实在是不够了,你还是要不停的往里面放对象,当然就崩溃了。

 

        

相关文章:

jvm的垃圾回收算法有哪些

jvm的垃圾回收算法有标记-清除、复制、标记-整理、分代回收算法,它们分别有不同的实现: 一、标记-清除算法 利用可达性分析算法分析之后,将未被标记的对象[即不可达对象]清除,以便回收它们所占用的内存。 缺点: 1、需…...

untiy 连接两个UI或一段固定一段跟随鼠标移动的线段

注意,仅适用于UI,且Canvas必须是Camera模式,不能用在3D物体上,3D物体请使用LineRenender 先创建一个图片,将锚点固定在左边 然后在脚本中添加如下内容 public RectTransform startObj;//起点物体public RectTransfor…...

如何成为顶级开源项目的贡献者

概述 对于程序员来讲,成为顶级开源项目的贡献者是一件有意义的事,当然,这也绝非易事。如果你正从事人工智能有关的工作,那么你一定了解诸如Google Tensorflow,Facebook Pytorch这样的开源项目。下面我们就说一说如何成…...

Threads and QObjects

QThread inherits QObject. It emits signals to indicate that the thread started or finished executing, and provides a few slots as well. QThread 派生于 QObject。QThread 会发射信号通知线程启动或终止执行任务,并且也会提供槽函数使用。 More interest…...

Tcp是怎样进行可靠准确的传输数据包的?

概述 很多时候,我们都在说Tcp协议,Tcp协议解决了什么问题,在实际工作中有什么具体的意义,想到了这些我想你的技术会更有所提升,Tcp协议是程序员编程中的最重要的一块基石,Tcp是怎样进行可靠准确的传输数据…...

[SWPUCTF 2022 新生赛]numgame

这道题有点东西网页一段计算框,只有加和减数字,但是永远到大不了20,页面也没啥特别的,准备看源码,但是打不开,我以为是环境坏掉了,看wp别人也这样,只不过大佬的开发者工具可以打开&a…...

java异常机制分析

java异常机制分析 本文实例分析了java的异常机制,分享给大家供大家参考。相信有助于大家提高大家Java程序异常处理能力。具体分析如下: 众所周知,java中的异常(Exception)机制很重要,程序难免会出错,异常机制可以捕获…...

浅谈Python中的内存管理 程序的内存布局

Python中的内存管理 Python 的内存管理是通过私有堆空间来实现的。这个私有堆内存中存储了所有 Python 对象和数据结构。Python 的解释器自身则拥有对堆空间的访问权,程序员不能直接访问这个私有堆,但可以通过解释器的 API 来进行某些操作。 以下是 Py…...

(具体解决方案)训练GAN深度学习的时候出现生成器loss一直上升但判别器loss趋于0

今天小陶在训练CGAN的时候出现了绷不住的情况,那就是G_loss(生成器的loss值)一路狂飙,一直上升到了6才逐渐平稳。而D_loss(判别器的loss值)却越来越小,具体的情况就看下面的图片吧。其实这在GAN…...

Redis 安装以及配置隧道连接

目录 1.CentOS 1. 安装Redis 2. Redis 启动和停⽌ 3. 操作Redis 2.Ubuntu 1. 安装Redis 2. Redis 启动/停⽌ 3. 操作 Redis 3.开启隧道 3.1 Xshell 配置隧道 3.2 windTerm 配置隧道 3.3 FinalShell配置隧道 4.可视化客户端连接 Another Redis Desktop Manager 1.Cen…...

FFmpeg 使用总结

FFmpeg 简介 FFmpeg的名称来自MPEG视频编码标准,前面的“FF”代表“Fast Forward”,FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。可以轻易地实现多种视频格式之间的相互转换。包括如下几个部分&#xf…...

出现Error: Cannot find module ‘compression-webpack-plugin‘错误

错误: 解决:npm install --save-dev compression-webpack-plugin1.1.12 版本问题...

Elasticsearch 摄取管道 — 检测到管道的死循环

在数据处理和摄取领域,管道在组织和自动化数据从源到目的地的流动方面发挥着至关重要的作用。 管道是数据按顺序通过的一系列处理阶段,每个阶段负责特定任务。 然而,有时,管道可能会遇到一个重大挑战,称为 “Cycle det…...

C# ListBox自动滚动方法

1、方法1:添加记录后,选择最后一条记录,让滚动条滚动到底部,再自动取消 listBox1.Items.Add(t ":a good day"); listBox1.SelectedIndex listBox1.Items.Count - 1; listBox1.SelectedIndex -1; //是否取消选中行…...

使用(Ajax原理)Promise + XHR实现请求数据

使用Promise XHR获取省份列表 步骤&#xff1a; * 1. 创建Promise对象 * 2. 执行XHR异步代码&#xff0c;获取省份列表 * 3. 关联成功或失败函数&#xff0c;做后续处理 代码示例 <script>// 1. 创建Promise对象const p new Promise((resolve,reject) > {// 2. 执行…...

【HTML】<input>

分类 text password number button reset submit hidden radio checkbox file image color range tel email&#xff08;火狐有校验&#xff0c;360浏览器无校验。&#xff09; url datetime&#xff08;火狐、360浏览器不支持&#xff09; search date、month、week、time、da…...

数据结构中一些零碎且易忘的知识点

树 并查集&#xff1a; 并查集的应用&#xff1a; 判断连通性、判环Kruskal算法排序并查集 并查集的存储方式 逻辑&#xff1a;双亲表示法的树存储&#xff1a;数组 并查集的时间复杂度&#xff08;m为并查集长度&#xff09; find&#xff1a;优化前为 O ( m ) O(m) O(m)&…...

2023上半年京东烘干机行业品牌销售排行榜(京东商品数据)

随着人们消费水平的提高&#xff0c;追求健康品质消费的用户越来越多&#xff0c;这样的消费升级为市场的发展带来很大的动力。同时&#xff0c;随着洗衣机市场趋向饱和&#xff0c;增长趋于平缓&#xff0c;更新换代和结构升级成为行业的主旋律。 在这一市场背景下&#xff0…...

ADS版图画封装学习笔记

ADS版图画封装 因为晶体管ATF54143在ADS中是没有封装的&#xff0c;所以要在ADS中画ATF54143的封装&#xff0c;操作步骤如下&#xff1a; 在ADS中新建layout&#xff0c;命名为ATF54143_layout&#xff0c; 根据datasheet知道封装的大小&#xff0c;进行绘制 在layout的con…...

空地协同智能消防系统——无人机、小车协同

1 题目 1.1 任务 设计一个由四旋翼无人机及消防车构成的空地协同智能消防系统。无人机上安装垂直向下的激光笔&#xff0c;用于指示巡逻航迹。巡防区域为40dm48dm。无人机巡逻时可覆盖地面8dm宽度区域。以缩短完成全覆盖巡逻时间为原则&#xff0c;无人机按照规划航线巡逻。发…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank&#xff1f;由于时间太久&#xff0c;我真忘记了。搜搜发现&#xff0c;还真有人和我一样。见下面的链接&#xff1a;https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾&#xff1a; 在上一篇中&#xff0c;我们成功地为应用集成了数据库&#xff0c;并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了&#xff01;但是&#xff0c;如果你仔细审视那些 API&#xff0c;会发现它们还很“粗糙”&#xff1a;有…...

算法岗面试经验分享-大模型篇

文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer &#xff08;1&#xff09;资源 论文&a…...

MFC 抛体运动模拟:常见问题解决与界面美化

在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...

在golang中如何将已安装的依赖降级处理,比如:将 go-ansible/v2@v2.2.0 更换为 go-ansible/@v1.1.7

在 Go 项目中降级 go-ansible 从 v2.2.0 到 v1.1.7 具体步骤&#xff1a; 第一步&#xff1a; 修改 go.mod 文件 // 原 v2 版本声明 require github.com/apenella/go-ansible/v2 v2.2.0 替换为&#xff1a; // 改为 v…...

STM32标准库-ADC数模转换器

文章目录 一、ADC1.1简介1. 2逐次逼近型ADC1.3ADC框图1.4ADC基本结构1.4.1 信号 “上车点”&#xff1a;输入模块&#xff08;GPIO、温度、V_REFINT&#xff09;1.4.2 信号 “调度站”&#xff1a;多路开关1.4.3 信号 “加工厂”&#xff1a;ADC 转换器&#xff08;规则组 注入…...

webpack面试题

面试题&#xff1a;webpack介绍和简单使用 一、webpack&#xff08;模块化打包工具&#xff09;1. webpack是把项目当作一个整体&#xff0c;通过给定的一个主文件&#xff0c;webpack将从这个主文件开始找到你项目当中的所有依赖文件&#xff0c;使用loaders来处理它们&#x…...

写一个shell脚本,把局域网内,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里

写一个shell脚本&#xff0c;把局域网内&#xff0c;把能ping通的IP和不能ping通的IP分类&#xff0c;并保存到两个文本文件里 脚本1 #!/bin/bash #定义变量 ip10.1.1 #循环去ping主机的IP for ((i1;i<10;i)) doping -c1 $ip.$i &>/dev/null[ $? -eq 0 ] &&am…...