垃圾收集算法

垃圾收集算法有如下几种:
        分代收集理论:年龄代和老年代选择各自的垃圾收集算法。
        复制算法:可达性分析算法找非垃圾对象,然后把非垃圾对象移动到另一端,这一端的垃圾对象清除,该方法浪费内存,用于年轻代。
        标记清除算法:非垃圾对象标记好,没有标记的全清除掉,存在效率问题(如果需要标记的对象太多,效率不高)、空间问题(标记清除后会产生大量不连续的碎片)
        标记整理算法:标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象回收。而是让所有存活的对象向一端移动,然后直接清理掉边界外的内存。

垃圾收集器

  • serial垃圾收集器(-XX:+UseSerialGC(年轻代使用) -XX:+UseSerialOldGC(FullGC时使用))
    其时单线程的,在进行垃圾收集工作的时候必须暂停其他所有工作线程(STW)。优势是单核时快,简单,易于理解,只能收集几十M到几百M。新生代采用复制算法,老年代使用标记整理算法。
  • Parallel Scavenge收集器(-XX:+useParallelGC(年轻代) -XX:UseParallelOldGC(老年代))
    STW时多线程收集,新生代采用复制算法,老年代采用标记整理算法。
  • ParNew收集器(-XX:+UseParNewGC)
    跟Parallel差不多,Parallel无法跟CMS配合。CMS是老年代的。
  • CMS收集器(-XX:+UseConcMarkSweepGC)
    JDK1.8默认年轻代和老年代是ParallelGC、ParallelOldGC,SWT时间长(内存大时)
    CMS收集器时一种以获取最短回收停顿时间为目标的收集器。它非常符合在注重用户体验的应用上使用,它是HotSpot虚拟机第一款真正意义上的并发收集器,它第一次实现了让垃圾收集线程与用户线程(基本上)同时工作。
    在这里插入图片描述
  • 初始标记:暂停所有其他线程(STW),并记录下gc roots直接能引用的对象,速度很快
  • 并发标记:并发标记阶段是从GC Root的直接关联对象开始遍历整个对象的过程,这个过程耗时较长,但不需要停顿用户线程,可以与赖叽收集器线程一起并发运行。因为用户线程继续运行,可能会导致已经标记的对象状态发生改变。
  • 重新标记:重新标记阶段就是为了修正并发标记期间因为用户程序继续运行而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间一般会比初始标记阶段的时间稍长,远远比并发标记时间短,主要用到三色标记里的增量更新算法啊,做重新标记。
  • 并发清理:开启用户线程,同时GC线程开始对胃标记的区域做清扫,这个阶段如果有新增对象会被标记为黑色不做任何处理。
  • 并发重置:重置本次GC过程中的标记数据。
    (Parallel更在意吞吐量,CPU执行垃圾收集的时间越短,吞吐量越高)
    缺点:对CPU资源敏感(会和服务抢资源)
               无法处理浮动垃圾(在并发标记和并发清理阶段又产生垃圾,这种浮动垃圾只能等到下一次再清理了)
               它使用的回收算法“标记-清除”算法会导致收集结束时会有大量空间碎片,当然可以通过参数-XX:+UseCMSCompactAtFullCollection可以让JVM再执行完标记清除后再做整理。
               执行过程中的不确定性,会存在上一次垃圾回收还没执行完,然后垃圾回收又被触发的情况。“特别是在并发标记和并发清理阶段会出现”,一边回收,系统一边运行,也许没回收完再次出发Full GC,也就是“concurrent mode failure”,此时会进入STW,用serial old垃圾收集器来回收。

CMS相关核心参数:

  • -XX:+UseConcMarkSweepGC:启用CMS
  • -XX:ConcGCThreads:并发的GC线程数
  • -XX:+UseCMSCompactAtFullCollection:Full GC之后做压缩整理(减少碎片)
  • -XX:CMSFullGCsBeforeCompaction:多次Full GC之后压缩一次,默认是0,代表每次Full GC后都会压缩一次。
  • -XX:CMSInitiatingOccupancyFraction:当老年代使用达到该比例时会出发Full GC(默认92,是百分比)
  • -XX:+UseCMSInitiatingOccupancyOnly:只使用设定的回收阀值,如果不指定,JVM仅在第一次使用设定值,后续则会自动调整
  • -XX:+CMSScavengeBeforeRemark:在CMS GC前启动一次minor gc,目的在于减少老年代对年轻代的引用,降低CMS GC的标记阶段的开销,一般CMS的GC耗时80%都在标记阶段
  • -XX:+CMSParallelInitialMarkEnabled:表示在初始标记的时候多线程执行,缩短STW
  • -XX:+CMSParallelRemarkEnabled:在重新标记的时候多线程执行,缩短STW

三色标记

        在并发标记过程中,因为标记期间应用程序还在继续跑,对象间的引用可能发生变化,多标或漏标的情况就有可能发生
        (三色标记)把我们所有的对象在GC可达性分析过程中,把对象分为3种:

  • 黑色:表示对象已经被垃圾收集器访问过,且这个对象的所有引用都已经扫描过。黑色对象代表已经扫描过,它是安全存活的,如果有其他对象引用指向了黑色对象,无须重新扫描一遍。黑色对象不可能直接(不经过灰色对象)指向某个白色对象。
  • 灰色:表示对象已经被垃圾收集器访问过,但这个对象上至少存在一个引用还没有被扫描过。
  • 白色:表示对象尚未被垃圾收集器访问过。显然在可达性分析刚刚开始的阶段,所有对象都是白色的,若在分析结束的阶段,仍然是白色的对象,即代表不可达。
    在这里插入图片描述
多标-浮动垃圾

在并发标记过程中,如果由于方法运行结束导致部分局部变量(gcroot)被销毁,这个gcroot引用的对象之前又被扫描过(被标记为非垃圾对象),那么本轮GC不会回收这部分内存这部分本应该回收但是没有回收到的内存,被称之为“浮动垃圾”。浮动垃圾并不会影响垃圾回收的正确性,只是需要等到下一轮垃圾回收中才被清除。
另外,针对并发标记(还有并发清理)开始后产生的新对象,通常的做法是直接全部当成黑色,本轮不会进行清除。这部分对象期间可能也会变为垃圾们,这也算是浮动垃圾的一部分。

漏标——读写屏障

       有两种解决方案:增量更新和原始快照。
       增量更新:在你的所有对象,如果在作赋值,把A的成员变量指向D,指针搞一个集合存起来,(重新标记过程中,找到之前记录的新增的引用,重新扫描A重新标记为灰色,灰色还会重新扫描)。把新增那些引用的源头和它引用的对象都记录到一个集合。重新标记为灰色,以后再扫。就是当黑色对象插入新的指向白色对象的引用关系时,就将这个新插入的引用记录下来,等并发扫描结束之后,再将这些记录过的引用关系中的黑色对象为根,重新扫描一次。这可以简化为黑色对象一旦新插入了指向白色对象的引用之后,它就变为灰色对象了。
       原始快照:就是当灰色对象要删除指向白色对象的引用关系时,就将这个要删除的引用记录下来,在并发扫描结束之后,再将这些记录过的引用关系中的灰色对象为根,重新扫描一次,这样就能扫到白色对象,将白色对象直接标为黑色。
       以上无论是对引用关系记录的插入还是删除,虚拟机的记录操作都是通过写屏障实现的。
       写屏障:要么在赋值操作之前,要么之后,把引用丢入集合,在写操作前面做一些事,后面做一些事,我们叫代码的操作屏障。
       现代追踪式(可达性分析)的垃圾回收器几乎都借鉴了三色标记的算法思想,尽管实现的方式不尽相同:比如白色/黑色集合一般都不会出现(但是有其他体现颜色的方法)、灰色集合可以通过栈/队列/缓存日志等方式进行实现、遍历方式可以式广度/深度遍历等等。
对于读写屏障,以Java HotSpot VM为例,其并发标记对漏标的处理方案如下:

  • CMS:写屏障+增量更新
  • G1,Shenandoah:写屏障+SATB
  • ZGC:读屏障

       工程实现中,读写屏障还有其他功能,比如写屏障可以用于记录跨代/区引用的变化,读屏障可以用于支持移动对象的并发执行等。功能之外,还有性能的考虑,所以对于选择哪种,每款垃圾回收器都有自己的想法。

记忆集与卡表

       JVM扫描时对跨代引用,如果一个对象被老年代引用,没办法通过gc root直接在年轻代找,在年轻代空间开辟了一小块区域维护老年代对年轻代所有的引用。跨代引用很少,用CardTable实现,只要有一个对象引用到年轻代对象,标记为dirty。CardTable底层实现是一个数组,除了记录是否为脏记录卡页的起始内存地址,根据起始地址找到卡页里所有对象,也加到年轻代的扫描机。卡页在老年代,维护每页的状态信息和地址在年轻代。

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

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

相关文章

SpringBoot解决Slow HTTP慢速攻击漏洞

项目场景: 扫描到的漏洞截图: 攻击原理: Web应用在处理HTTP请求之前都要先接收完所有的HTTP头部,因为HTTP头部中包含了一些Web应用可能用到的重要的信息。攻击者利用这点,发起一个HTTP请求,一直不停的发送…

〖大前端 - ES6篇①〗- ES6简介

说明:该文属于 大前端全栈架构白宝书专栏,目前阶段免费,如需要项目实战或者是体系化资源,文末名片加V!作者:哈哥撩编程,十余年工作经验, 从事过全栈研发、产品经理等工作,目前在公司…

burp靶场--host攻击

burp靶场–host攻击 https://portswigger.net/web-security/host-header#what-is-an-http-host-header-attack 在本节中,我们将讨论错误配置和有缺陷的业务逻辑如何通过 HTTP 主机标头使网站遭受各种攻击。我们将概述用于识别易受 HTTP 主机标头攻击的网站的高级方…

PolarDB无感切换特性助力游戏领域高可用实践

❤️作者主页:小虚竹 ❤️作者简介:大家好,我是小虚竹。2022年度博客之星评选TOP 10🏆,Java领域优质创作者🏆,CSDN博客专家🏆,华为云享专家🏆,掘金年度人气作…

零代码编程:用ChatGPT智能批量删除文件标题中的某些字符

文件里面有很多个mp4视频文件,要批量删除文件标题中的“Little Fox - ”“Level 04”、“Level 4”、“Level04”“ - ”、“-”、“_”等字母和符号。 在ChatGPT中输入提示词如下: 你是一个Python编程专家,要完成一个批量重命名文件标题的任…

【wu-framework-parent 1.2.2-JDK17-SNAPSHOT 新版本中的 ACW】

版本: 1.2.2-JDK17-SNAPSHOT 项目地址:https://gitee.com/wujiawei1207537021/wu-framework-parent/tree/master/wu-smart-intergration/wu-smart-acw 演示地址:http://124.222.48.62:30193/wu-smart-acw-ui/index.html admin/admin docker启动 dock…

AI大概不会很快抢走你的饭碗哦!

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

Unity3d引擎中使用AIGC生成的360全景图(天空盒)

前言 在这里与Skybox AI一起,一键打造体验无限的360世界,这是这个AIGC一键生成全景图的网站欢迎语。 刚使用它是23年中旬,在没有空去给客户实地拍摄全景图时,可以快速用它生成一些相关的全景图,用作前期沟通的VR de…

数据结构——Java实现栈和队列

一、栈 Stack 1.特点 (1)栈是一种线性数据结构 (2)规定只能从栈顶添加元素,从栈顶取出元素 (3)是一种先进后出的数据结构(Last First Out)LIFO 2.具体实现 Java中可…

Zookeeper集群

一、Zookeeper概述 1.1 Zookeeper 定义 Zookeeper是一个开源的分布式的,为分布式框架提供协调服务的Apache项目。 1.2 Zookeeper 工作机制 Zookeeper从设计模式角度来理解:是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理…

华夏基金“冰火两重天”:产品增量不增值,靠什么赢得用户?

近日,华夏基金发布关于华夏野村日经225交易型开放式指数证券投资基金(QDII)(下称“华夏野村日经ETF”)二级市场交易价格溢价风险提示及临时停牌公告。 公告内容显示,华夏野村日经ETF二级市场交易价格明显高…

备战2个月,面试被问麻了....

🔥 交流讨论:欢迎加入我们一起学习! 🔥 资源分享:耗时200小时精选的「软件测试」资料包 🔥 教程推荐:火遍全网的《软件测试》教程 📢欢迎点赞 👍 收藏 ⭐留言 &#x1…

为什么静态IP是您批量创建社交媒体和账户管理必备?

“新设备登录请求被拒绝,请使用常用设备登录。”谁没有遇到过远程管理社交或商业账户时登录被拒的情况呢? 更糟糕的情况可能是遇到这样的提示:“您的账号可能被盗用,暂时限制使用。请按要求进行身份验证。” 最坏的结果则可能是因为各种原…

工业RFID读卡器的功能和作用

工业读卡器主要用于识别和读写特定目标的数据,它的种类有很多,有分体的读写器也有一体的读写器,根据不同场景的应用可以选择不同的读写器。 工业RFID读卡器的功能和作用 工业RFID读卡器在工业自动化和物流管理等领域中发挥着重要作用。其主要…

什么是DDoS攻击?

什么是DDoS攻击? 拒绝服务(Denial-of-Service,DoS)攻击是一种针对某些服务可用性的攻击。 通过耗尽CPU、内存、带宽以及磁盘空间等系统资源,来阻止或削弱对网络、系统或应用程序的授权使用的行为。 如果攻击者采用单一…

动态权限有哪些

定位权限: ACCESS_FINE_LOCATION:精确位置ACCESS_COARSE_LOCATION:大致位置 相机权限: CAMERA:访问摄像头 存储权限: READ_EXTERNAL_STORAGE:读取外部存储WRITE_EXTERNAL_STORAGE:…

springboot集成easypoi

easypoi,主打的功能就是容易,通过简单的配置&#xff0c;就可以方便的写出Excel导出,Excel模板导出,Excel导入,Word模板导出 pom导入依赖 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-star…

SpringCloud Aliba-Seata【上】-从入门到学废【7】

目录 &#x1f9c2;.Seata是什么 &#x1f32d;2.Seata术语表 &#x1f953;3.处理过程 &#x1f9c8;4.下载 &#x1f37f;5.修改相关配置 &#x1f95e;6.启动seata 1.Seata是什么 Seata是一款开源的分布式事务解决方案&#xff0c;致力于在微服务架构下提供高性能…

【C++修行之道】STL(初识pair、vector)

目录 一、pair 1.1pair的定义和结构 1.2pair的嵌套 1.3pair自带排序规则 1.4代码示例 二、vector 2.1vector的定义和特性 2.2vector的初始化 一维初始化&#xff1a; 2.3vector的常用函数 2.4vector排序去重 排序: 去重&#xff1a; 示例&#xff1a; 一、pair …