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”内存溢出了。因为内存实在是不够了,你还是要不停的往里面放对象,当然就崩溃了。

 

        

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

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

相关文章

flask------消息闪现 flash

1介绍 flask提供了一个非常有用的flash()函数,它可以用来“闪现”需要提示给用户的消息,比如当用户登录成功后显示“欢迎回来!”。在视图函数调用flash()函数,传入消息内容,flash()函数把消息存…

TPlink DDNS 内网穿透?外网访问设置方法

有很多小伙伴都想知道:TPlink路由器怎么设置DDNS内网穿透?今天,小编就给大家分享一下TPlink DDNS 外网访问设置方法,下面是图文教程,帮助新手快速入门DDNS设置。 本文介绍的是云路由器TP-LINK DDNS的设置方法。TP-LIN…

R-Meta分析教程

详情点击链接:R-Meta模型教程 一:Meta分析的选题与文献计量分析CiteSpace应用 1、Meta分析的选题与文献检索 1)什么是Meta分析? 2)Meta分析的选题策略 3)文献检索数据库 4)精确检索策略,如何检索全、检索准 5)文献的管理与…

浏览器同源策略

浏览器同源策略 同源策略:是一个重要的浏览器的安全策略,用于限制一个源的文档或者它加载的脚本如何能与另一个源的资源进行交互 它能帮助阻隔恶意文档,减少可能被攻击的媒介 例如:被钓鱼网站收集信息,使用ajax发起…

DevOps系列文章之 Docker 安装 NFS 服务器

Docker 安装 NFS 服务器 环境: 192.186.2.105 NFS 服务器 192.168.2.106 Client 客户端 安装 一、服务器端 https://github.com/f-u-z-z-l-e/docker-nfs-server 1、创建目录 mkdir /nfsdata mkdir -p /docker/nfs/2、启动脚本 vim start.sh# 内容 docker run …

[国产MCU]-BL602开发实例-GPIO控制

GPIO与控制 文章目录 GPIO与控制1、GPIO介绍2、GPIO管理相关API介绍3、硬件准备4、软件准备5、代码实现3.1 GPIO输出3.2 GPIO输入3.3 GPIO中断BL602的GLB(Global Register)是芯片通用全局设定模块,主要包含了时钟管理、复位管理、总线管理、内存管理以及GPIO管理等功能。 本文…

shell脚本自动打包部署

1、安装git 2、使用Git克隆代码 3、安装Maven (1) tar -zxvf ** 解压文件 (2)修改配置 (3)source /etc/profile 重新加载一下文件 (4)mvn -version 查看版本号 已经安装成…

线程池的使用案例一

一、配置线程池 1、不推荐的方式 ExecutorService executorService Executors.newFixedThreadPool(); // 创建⼀个固定⼤⼩的线程池,可控制并发的线程数,超出的线程会在队列中等待; ExecutorService executorService Executors.newCache…

基于Java+SpringBoot+Vue的篮球竞赛预约平台设计与实现(源码+LW+部署文档等)

博主介绍: 大家好,我是一名在Java圈混迹十余年的程序员,精通Java编程语言,同时也熟练掌握微信小程序、Python和Android等技术,能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

C# 简单模拟 程序内部 消息订阅发布功能

文章目录 前言模拟消息订阅发布使用注意事项 前言 我想做个简单的消息发布订阅功能,但是发现好像没有现成的工具类。要么就是Mqtt这种消息订阅发布。但是我只想程序内部进行消息订阅发布,进行程序的解耦。那没办法了,只能自己上了 模拟消息…

【JavaSE】String类中常用的字符串方法(超全)

目录 1.求字符串的长度 2.判断字符串是否为空 3.String对象的比较 3.1 判断字符串是否相同 3.2 比较字符串大小 3.3 忽略大小写比较 4.字符串查找 5.转化 5.1 数值和字符串转化 5.1.1 数字转字符串 valueof 5.1.2 valueOf的其他用法 5.1.3 字符串转数字 5.2 大小写转…

【Shell】基础语法(二)

文章目录 一、Shell基本语法文件名代换命令代换算术代换转义字符引号 二、Shell脚本语法条件测试分支结构循环 三、总结 一、Shell基本语法 文件名代换 用于匹配的字符称为通配符(Wildcard),如:* ? [ ] 具体如下: *…

3个月拿下华为测试岗,早知道华为这么好进,我就...

先说一下我的情况,某211本科计算机专业,之前在深圳那边做了大约半年多少儿编程老师,之后内部平调回长沙这边,回来之后发现有点难,这边可能是业绩难做,虚假承诺很厉害,要给那些家长虚假承诺去骗人…

暗黑版GPT流窜暗网 降低犯罪门槛

随着AIGC应用的普及,不法分子利用AI技术犯罪的手段越来越高明,欺骗、敲诈、勒索也开始与人工智能沾边。 近期,专为网络犯罪设计的“暗黑版GPT”持续浮出水面,它们不仅没有任何道德界限,更没有使用门槛,没有…

代码随想录一刷总结

为期60天的代码随想录算法训练营结束了,中间想放弃过,敷衍过,但是最终还是完成了,给我自己和打满60天卡的小伙伴们一个赞。这60天的从一个算法小白到刚刚入门,虽然只是小小一步,却并不容易,至少…

EtherCAT转Profinet网关连接西门子PLC与凯福科技总线步进驱动器通讯

西门子S7-1200/1500系列的PLC,采用Profinet实时以太网通讯协议,需要连接带EtherCAT的通讯功能的伺服驱动器等设备,就必须进行通讯协议转换。捷米特JM-EIP-RTU系列的网关提供了,快速可行的解决方案 捷米特JM-ECTM-PN在PROFINET一侧…

tomcat

1. 简述静态网页和动态网页的区别。 静态网页是指在服务器存储的网页内容保持不变,不会根据用户的请求或其他条件而改变。它的内容是固定的,无法根据用户的不同需求进行个性化或实时更新。静态网页一般由HTML、CSS和JavaScript等静态资源组成&#xff0…

linux文件描述符fd

文件描述符 fd是一个>0 的整数 每打开一个文件,就创建一个文件描述符,通过文件描述符来操作文件 预定义的文件描述符: 0:标准输入,对应于已打开的标准输入设备(键盘) 1:标准输出,对应于已打开的标准输出设备(控制台) 2.标准错误…

java异常机制分析

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

智慧水利整体解决方案[43页PPT]

导读:原文《智慧水利整体解决方案[43页PPT]》(获取来源见文尾),本文精选其中精华及架构部分,逻辑清晰、内容完整,为快速形成售前方案提供参考。 完整版领取方式 完整版领取方式: 如需获取完整的…