jvm垃圾收集器与三色算法

2023-11-10 10:40

本文主要是介绍jvm垃圾收集器与三色算法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

首先要写垃圾收集算法(针对堆空间)

 垃圾收集算法包含 分代收集理论、复制算法、标记整理算法、标记清除算法分代收集理论是 堆空间分为新生代老年代  分代收集理论就是判断新生代用什么垃圾回收器老年代用什么垃圾回收器 
复制算法、标记整理算法、标记清除算法 根据分代收集理论从而告诉用什么垃圾收集器(垃圾收集器实现了复制算法、标记整理算法、标记清除算法) 这三个其中一个复制算法 一般针对新生代 比如新生代的一块内存 它会把这个内存空间分成两半一般是用来存储对象另一半是未使用的空间当存储对象的那半空间满了就会触发minor GC  把那半存储对象的内存空间进行回收 然后把存活的对象放到未使用的那半内存中 它还会把内存做一下整理 下一次minor GC时也是这样 就是来回复制标记清除算法  是做gc时会用gc root标记非垃圾对象  标记完就把没有标记的对象清除 它会有缺点 如果内存很大那么它标记的时间就会很长  清除垃圾对象之后还会留下内存碎片   一般用在老年代标记整理算法  是做gc时会用gc root标记非垃圾对象  标记完就把这些非垃圾对象向上移动到那些垃圾对象的内存空间往上 也就是做了一个从新赋值的操作 但是如果垃圾对象在内存空间的最后一行那么就需要手动的清理垃圾收集器(后面会有张垃圾收集器的图谱) 就是实现了上面说复制算法、标记清除算法、标记整理算法Serial(读音谁瑞要)(新生代使用)---Serial Old(老年代使用)---CMS(老年代使用) // 这里表示新生代垃圾回收器可以跟哪些老年代垃圾回收器做配合ParNew(读音怕牛)(新生代使用) --- Serial Old(老年代使用)--- CMS(老年代使用)// 这里表示新生代垃圾回收器可以跟哪些老年代垃圾回收器做配合Parallel(读音拍累瑞要)(新生代使用)--- Parallel Old(老年代使用)--- Serial Old(老年代使用)// 这里表示新生代垃圾回收器可以跟哪些老年代垃圾回收器做配合当然垃圾回收器还有好的这里 后续会在写几个 以上的垃圾回收器在JDK1.8算是最稳定的了

Serial收集器(-XX:+UseSerialGC年轻代 -XX:+UseSerialOldGC老年代)

Serial(串行)收集器是最老的一个 它是一个单线程的收集器 单线程的意思不是只用一个垃圾线程去收集垃圾而是当它做垃圾收集的时候会把其他所以线程的工作停止(Stop The World 读音死到破 泽 我的)直到它垃圾收集结束 它新生代使用复制算法 老年代使用标记整理算法(后面会有张关于它的图) 现在一般都使用JDK1.8它的作用主要就是给CMS收集器做后备方案Parallel Scavenge(读音怕累瑞要 死噶为吃)收集器(-XX:UseParallelGC年轻代-XX:UseParallelOldGC老年代) JDK8默认使用这个收集器其实就是Serial收集器的多线程版本 它的默认线程数与cpu线程数一样(可以通过-XX:ParallelGCThreads制定线程数 一般不要修改) 这个收集器关注点是吞吐量(cpu执行效率)CMS等垃圾收集器关注点为用户线程停止的时间   新生代使用复制算法 老年代使用标记整理算法ParNew收集器(-XX:UseParNewGC) 这个收集器跟Parallel收集器很类似 区别就是ParNew可以跟CMS收集器做配合而Parallel收集器不可以  ParNew收集器是一个新生代的收集器  使用复制算法CMS收集器(-XX:UseConcMarkSweepGC)使用标记清楚算法(老年代收集器)后面会有图CMS全称(Concurrent Mark Sweep 读音炕卡伦特 猫可 死为铺)它是以stw时间最短作为目标 它第一次实现了让用户线程跟垃圾线程同时工作  它主要有五个 初始标记、并发标记、重新标记、并发清理、并发重置初始标记会stw 主要标记了 A a = new A() a指向new A() 而new A()中的那些引用类型的成员变量还没有标记  会stw并发标记在初始标记的基础上继续往下标记 开始找new A()中那些引用类型的成员变量 (gc root)不会stw重新标记 因为在并发标记时 是跟用户线程同时工作 可能会出现因为用户线程导致那些本来是垃圾的对象变成不是垃圾了把它又重新赋值了  那些不是垃圾的变成垃圾  并发标记就是在这基础上再检查一遍并做出相应的处理 会stw并发清除 这一步就开始根据重新标记的结果清理垃圾 如果有新的对象产生它会把这个对象标记为黑色 不会stw并发重置 是把那些标记的gc root根节点取消标记 不会stwCMS会有一些问题在并发标记时会有垃圾对象未标记 而造成无法清理这个垃圾或者一些垃圾 这种垃圾称为“浮动垃圾” 它的解决办法就是等下次gc时再做处理 它还会跟跟用户线程抢夺cpu时间片 这个其实不算是问题但是也有 还有CMS采用的是标记清除算法 那么它就会造成大量的内存碎片 这个问题可以通过(-XX:UseCMSComPactAtFullCollection这个jvm指令让它在标记清除完之后做内存碎片的整理)  执行过程中会有不确定的因素 会存在这次gc还没完成又触发gc 这时会触发CMS的并发失败concurrent mode failure(读音炕卡伦特 猫到 fai要也) 机制如果触发了这个机制那么就会进入Stop The Wrod 并换成serial old收集器做垃圾回收工作  因为serial old收集器是单线程 它的效率是非常低的 所以一定不能让它出现并发失败问题 这个问题可以通过(-XX:CMSInitiatingOccupancyFraction 这个指令表示老年代的内存达到多少让它触发gc默认百分之92 具体大小要通过分析系统进行设置)

CMS的相关核心参数

  1. -XX:+UseConcMarkSweepGC:启用cms

  2. -XX:ConcGCThreads:并发的GC线程数

  3. -XX:+UseCMSCompactAtFullCollection:FullGC之后做压缩整理(减少碎片)

  4. -XX:CMSFullGCsBeforeCompaction:多少次FullGC之后压缩一次,默认是0,代表每次FullGC后都会压缩一次

  5. -XX:CMSInitiatingOccupancyFraction: 当老年代使用达到该比例时会触发FullGC(默认是92,这是百分比)

  6. -XX:+UseCMSInitiatingOccupancyOnly:只使用设定的回收阈值(-XX:CMSInitiatingOccupancyFraction设定的值),如果不指定,JVM仅在第一次使用设定值,后续则会自动调整

  7. -XX:+CMSScavengeBeforeRemark:在CMS GC前启动一次minor gc,目的在于减少老年代对年轻代的引用,降低CMS GC的标记阶段时的开销,一般CMS的GC耗时 80%都在标记阶段

  8. -XX:+CMSParallellnitialMarkEnabled:表示在初始标记的时候多线程执行,缩短STW9. -XX:+CMSParallelRemarkEnabled:在重新标记的时候多线程执行,缩短STW;亿级流量电商系统如何优化JVM参数设置(ParNew+CMS)

垃圾收集底层算法实现

三色标记
在程序运行中并发标记会出现 多标、漏标的情况 多标就是把一个垃圾对象标记为非垃圾对象也就是浮动垃圾等下次gc再做处理即可 而漏标就是一个非垃圾对象没有被标记为非垃圾对象 这就是一个很严重的问题了一个对象正在用 而垃圾收集器把它给清理了是一个很严重的问题

三色标记 这里用黑色、灰色、白色黑色表示已经被gc root扫描完的对象灰色表示gc root扫描了但是还没扫描完白色表示未被gc root扫描的对象public class A{ B b = new B(); C c = null;}public class B{ D d = new D();C c = new C();}public class C{}public class D{}A a = new A()C c = a.b.c;a.c = a.b.c;a.b.c = null;以上是故事背景 CMS收集器环境下 下面说的都是假设一个故事这里表达的什么是漏标 就是当A a = new A()这个以及做完gcroot 标记为黑色 可以扫描完一定有做了并发标记 并发标记跟用户线程一起的也就是说 C c = a.b.c;这样代码下面的代码也在执行 可以看到a.c=a.b.c然后又给a.b.c=null; 然后上面说扫描A扫描完了 但是这个扫描完了定义是指A类中的扫描了b跟c是否有指向一个对象实例 但是这个对象实例还没进入类中扫描 也就是B类中的c跟d 这种情况A类是标记为黑色因为它里面的变量以及扫描完了 B类假设扫描到了d还没扫描c 会把B标记为灰色 这时用户线程把a类中的c变量给赋值了赋值的为a类中的b类中的c 下面又把这个c给赋值为null A标记为黑色对象了无法再被扫描了这就是漏标的情况 B类是灰色在重新标记时会扫描   漏标解决方法增量更新 原始快照

漏标 -读写屏障 (这是一个概念)

增量更新 黑色对象一旦新插入了指向白色对象的引用时它就会变成灰色对象

原始快照 就是当灰色对象删除了一个指向白色对象的引用时 会把这个引用记录下来 确保不会被删除 就算是垃圾就让它变成浮动垃圾 在下次gc时处理

写屏障 在java HotSpot VM(java源码)中 在赋值操作前后给它做一些什么什么操作 就是有两个队列一个赋值操作前的队列一个赋值操作后的队列

读屏障 就是在读取这个变量的内存地址时前后做些什么事

CMS 处理漏标的方案 写屏障+增量更新

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这篇关于jvm垃圾收集器与三色算法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/382129

相关文章

Java设计模式---迭代器模式(Iterator)解读

《Java设计模式---迭代器模式(Iterator)解读》:本文主要介绍Java设计模式---迭代器模式(Iterator),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录1、迭代器(Iterator)1.1、结构1.2、常用方法1.3、本质1、解耦集合与遍历逻辑2、统一

Java内存分配与JVM参数详解(推荐)

《Java内存分配与JVM参数详解(推荐)》本文详解JVM内存结构与参数调整,涵盖堆分代、元空间、GC选择及优化策略,帮助开发者提升性能、避免内存泄漏,本文给大家介绍Java内存分配与JVM参数详解,... 目录引言JVM内存结构JVM参数概述堆内存分配年轻代与老年代调整堆内存大小调整年轻代与老年代比例元空

深度解析Java DTO(最新推荐)

《深度解析JavaDTO(最新推荐)》DTO(DataTransferObject)是一种用于在不同层(如Controller层、Service层)之间传输数据的对象设计模式,其核心目的是封装数据,... 目录一、什么是DTO?DTO的核心特点:二、为什么需要DTO?(对比Entity)三、实际应用场景解析

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操

从原理到实战深入理解Java 断言assert

《从原理到实战深入理解Java断言assert》本文深入解析Java断言机制,涵盖语法、工作原理、启用方式及与异常的区别,推荐用于开发阶段的条件检查与状态验证,并强调生产环境应使用参数验证工具类替代... 目录深入理解 Java 断言(assert):从原理到实战引言:为什么需要断言?一、断言基础1.1 语

深度解析Java项目中包和包之间的联系

《深度解析Java项目中包和包之间的联系》文章浏览阅读850次,点赞13次,收藏8次。本文详细介绍了Java分层架构中的几个关键包:DTO、Controller、Service和Mapper。_jav... 目录前言一、各大包1.DTO1.1、DTO的核心用途1.2. DTO与实体类(Entity)的区别1

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.

SpringBoot整合liteflow的详细过程

《SpringBoot整合liteflow的详细过程》:本文主要介绍SpringBoot整合liteflow的详细过程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋...  liteflow 是什么? 能做什么?总之一句话:能帮你规范写代码逻辑 ,编排并解耦业务逻辑,代码

JavaSE正则表达式用法总结大全

《JavaSE正则表达式用法总结大全》正则表达式就是由一些特定的字符组成,代表的是一个规则,:本文主要介绍JavaSE正则表达式用法的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录常用的正则表达式匹配符正则表China编程达式常用的类Pattern类Matcher类PatternSynta

Spring Security中用户名和密码的验证完整流程

《SpringSecurity中用户名和密码的验证完整流程》本文给大家介绍SpringSecurity中用户名和密码的验证完整流程,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定... 首先创建了一个UsernamePasswordAuthenticationTChina编程oken对象,这是S