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是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。可以轻易地实现多种视频格式之间的相互转换。包括如下几个部分…...
出现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获取省份列表 步骤: * 1. 创建Promise对象 * 2. 执行XHR异步代码,获取省份列表 * 3. 关联成功或失败函数,做后续处理 代码示例 <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(火狐有校验,360浏览器无校验。) url datetime(火狐、360浏览器不支持) search date、month、week、time、da…...
数据结构中一些零碎且易忘的知识点
树 并查集: 并查集的应用: 判断连通性、判环Kruskal算法排序并查集 并查集的存储方式 逻辑:双亲表示法的树存储:数组 并查集的时间复杂度(m为并查集长度) find:优化前为 O ( m ) O(m) O(m)&…...
2023上半年京东烘干机行业品牌销售排行榜(京东商品数据)
随着人们消费水平的提高,追求健康品质消费的用户越来越多,这样的消费升级为市场的发展带来很大的动力。同时,随着洗衣机市场趋向饱和,增长趋于平缓,更新换代和结构升级成为行业的主旋律。 在这一市场背景下࿰…...
ADS版图画封装学习笔记
ADS版图画封装 因为晶体管ATF54143在ADS中是没有封装的,所以要在ADS中画ATF54143的封装,操作步骤如下: 在ADS中新建layout,命名为ATF54143_layout, 根据datasheet知道封装的大小,进行绘制 在layout的con…...
空地协同智能消防系统——无人机、小车协同
1 题目 1.1 任务 设计一个由四旋翼无人机及消防车构成的空地协同智能消防系统。无人机上安装垂直向下的激光笔,用于指示巡逻航迹。巡防区域为40dm48dm。无人机巡逻时可覆盖地面8dm宽度区域。以缩短完成全覆盖巡逻时间为原则,无人机按照规划航线巡逻。发…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...
JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...
【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
