干掉cms,zgc才是未来

[原创]JVM垃圾回收机制和常见垃圾收集器-CMS、G1、ZGC 现代大部分的虚拟机的垃圾回收器都遵循“分代收集”的理论基础来进行设计实现: 根据这个理论基础,JVM的大部分虚拟机将堆空间逻辑划分为新生代/年轻代、老年代,垃圾收集器可以根据不同的区域选择不同的回收算法进行GC。 将内存分隔为两块相同大小的区域,每次只使用其中的一块,每当GC完成后,将存活的对象复制到另一块区域,然后将前一块清空。分为标记和清除两个阶段,标记存活的对象,然后GC清除掉没有被标记的对象。这种算法实现简单,但是有2个缺点... 阅读详情

点击上方“芋道源码”,选择“设为星标”

管她前浪,还是后浪?

能浪的浪,才是好浪!

每天 8:55 更新文章,每天掉亿点点头发...

源码精品专栏

 


JAVA程序最爽的地方是它的GC机制,开发人员不需要关注内存申请和回收问题。同时,JAVA程序最头疼的地方也是它的GC机制,因为掌握JVM和GC调优是一件非常困难的事情。

在ParallelOldGC、CMS、G1之后,JDK11带来的全新的「ZGC」为我们解决了什么问题?Oracle官方介绍它是一个Scalable、Low Latency的垃圾回收器。所以它的目的是「降低停顿时间」,由此会导致吞吐量会有所降低。吞吐量降低问题不大,横向扩展几台服务器就能解决问题了啦。

ZGC目标

如下图所示,ZGC的目标主要有4个:

支持TB量级的堆。这你受得了吗?我们生产环境的硬盘还没有上TB呢,这应该可以满足未来十年内,所有JAVA应用的需求了吧。

最大GC停顿时间不超10ms。这你受得了吗?目前一般线上环境运行良好的JAVA应用Minor GC停顿时间在10ms左右,Major GC一般都需要100ms以上(G1可以调节停顿时间,但是如果调的过低的话,反而会适得其反),之所以能做到这一点是因为它的停顿时间主要跟Root扫描有关,而Root数量和堆大小是没有任何关系的。

奠定未来GC特性的基础。牛逼,牛逼!

最糟糕的情况下吞吐量会降低15%。这都不是事,停顿时间足够优秀。至于吞吐量,通过扩容分分钟解决。

图片

另外,Oracle官方提到了它最大的优点是:它的停顿时间不会随着堆的增大而增长!也就是说,几十G堆的停顿时间是10ms以下,几百G甚至上T堆的停顿时间也是10ms以下。

ZGC概述

接下来从几个维度概述一下ZGC。

  • New GC

  • Single Generation

  • Region Based

  • Partial Compaction

  • NUMA-aware

  • Colored Pointers

  • Load Barriers

  • ZGC tuning

  • Change Log

New GC

ZGC是一个全新的垃圾回收器,它完全不同以往HotSpot的任何垃圾回收器,比如:PS、CMS、G1等。如果真要说它最像谁的话,那应该是Azul公司的商业化垃圾回收器:「C4」,ZGC所采用的算法就是Azul Systems很多年前提出的Pauseless GC,而实现上它介于早期Azul VM的Pauseless GC与后来Zing VM的C4之间。不过需要说明的是,JDK11中ZGC只能运行在Linux64操作系统之上。JDK14新增支持了MacOS和Window平台:

图片

如下图所示,是ZGC和Parallel以及G1的压测对比结果(CMS在JDK9中已经被标记deprecated,更高版本中已经被彻底移除,所以不在对比范围内)。我们可以明显的看到,停顿时间方面,ZGC是100%不超过10ms的,简直是秒天秒地般的存在:

图片

接下来,再看一下ZGC的垃圾回收过程,如下图所示。由图我们可知,ZGC依然没有做到整个GC过程完全并发执行,依然有3个STW阶段,其他3个阶段都是并发执行阶段:

图片

Pause Mark Start

这一步就是初始化标记,和CMS以及G1一样,主要做Root集合扫描,「GC Root是一组必须活跃的引用,而不是对象」。例如:活跃的栈帧里指向GC堆中的对象引用、Bootstrap/System类加载器加载的类、JNI Handles、引用类型的静态变量、String常量池里面的引用、线程栈/本地(native)栈里面的对象指针等,但不包括GC堆里的对象指针。所以这一步骤的STW时间非常短暂,并且和堆大小没有任何关系。不过会根据线程的多少、线程栈的大小之类的而变化。

图片

Concurrent Mark/Remap

第二步就是并发标记阶段,这个阶段在第一步的基础上,继续往下标记存活的对象。并发标记后,还会有一个短暂的暂停(Pause Mark End),确保所有对象都被标记。

图片

Concurrent Prepare for Relocate

即为Relocation阶段做准备,选取接下来需要标记整理的Region集合,这个阶段也是并发执行的。接下来又会有一个Pause Relocate Start步骤,它的作用是只移动Root集合对象引用,所以这个STW阶段也不会停顿太长时间。

图片

Concurrent Relocate

最后,就是并发回收阶段了,这个阶段会把上一阶段选中的需要整理的Region集合中存活的对象移到一个新的Region中(这个行为就叫做「Relocate」,即重新安置对象),如上图所示。Relocate动作完成后,原来占用的Region就能马上回收并被用于接下来的对象分配。细心的同学可能有疑问了,这就完了?Relocate后对象地址都发生变化了,应用程序还怎么正常操作这些对象呢?这就靠接下来会详细说明的Load Barrier了。

Single Generation

单代,即ZGC「没有分代」。我们知道以前的垃圾回收器之所以分代,是因为源于“「大部分对象朝生夕死」”的假设,事实上大部分系统的对象分配行为也确实符合这个假设。

那么为什么ZGC就不分代呢?因为分代实现起来麻烦,作者就先实现出一个比较简单可用的单代版本。用符合我们国情的话来解释,大概就是说:工作量太大了,人力又不够,老板,先上个1.0版本吧!!!

Region Based

这一点和G1一样,都是基于Region设计的垃圾回收器,ZGC中的Region也被称为「ZPages」,ZPages被动态创建,动态销毁。不过,和G1稍微有点不同的是,G1的每个Region大小是完全一样的,而ZGC的Region大小分为3类:2MB,32MB,N×2MB,如此一来,灵活性就更好了:

图片

Partial Compaction

部分压缩,这一点也很G1类似。以前的ParallelOldGC,以及CMS GC在压缩Old区的时候,无论Old区有多大,必须整体进行压缩(CMS GC默认情况下只是标记清除,只会发生FGC时才会采用Mark-Sweep-Compact对Old区进行压缩),如此一来,Old区越大,压缩需要的时间肯定就越长,从而导致停顿时间就越长。

而G1和ZGC都是基于Region设计的,在回收的时候,它们只会选择一部分Region进行回收,这个回收过程采用的是Mark-Compact算法,即将待回收的Region中存活的对象拷贝到一个全新的Region中,这个新的Region对象分配就会非常紧凑,几乎没有碎片。垃圾回收算法这一点上,和G1是一样的。

NUMA-aware

NUMA对应的有UMA,UMA即Uniform Memory Access Architecture,NUMA就是Non Uniform Memory Access Architecture。UMA表示内存只有一块,所有CPU都去访问这一块内存,那么就会存在竞争问题(争夺内存总线访问权),有竞争就会有锁,有锁效率就会受到影响,而且CPU核心数越多,竞争就越激烈。NUMA的话每个CPU对应有一块内存,且这块内存在主板上离这个CPU是最近的,每个CPU优先访问这块内存,那效率自然就提高了:

图片

服务器的NUMA架构在中大型系统上一直非常盛行,也是高性能的解决方案,尤其在系统延迟方面表现都很优秀。ZGC是能自动感知NUMA架构并充分利用NUMA架构特性的。

Colored Pointers

Colored Pointers,即颜色指针是什么呢?如下图所示,ZGC的核心设计之一。以前的垃圾回收器的GC信息都保存在对象头中,而ZGC的GC信息保存在指针中。每个对象有一个64位指针,这64位被分为:

  • 18位:预留给以后使用;

  • 1位:Finalizable标识,次位与并发引用处理有关,它表示这个对象只能通过finalizer才能访问;

  • 1位:Remapped标识,设置此位的值后,对象未指向relocation set中(relocation set表示需要GC的Region集合);

  • 1位:Marked1标识;

  • 1位:Marked0标识,和上面的Marked1都是标记对象用于辅助GC;

  • 42位:对象的地址(所以它可以支持2^42=4T内存):

    图片

通过对配置ZGC后对象指针分析我们可知,对象指针必须是64位,那么ZGC就无法支持32位操作系统,同样的也就无法支持压缩指针了(CompressedOops,压缩指针也是32位)。

Load Barriers

这个应该翻译成读屏障(与之对应的有写屏障即Write Barrier,之前的GC都是采用Write Barrier,这次ZGC采用了完全不同的方案),这个是ZGC一个非常重要的特性。在标记和移动对象的阶段,每次「从堆里对象的引用类型中读取一个指针」的时候,都需要加上一个Load Barriers。那么我们该如何理解它呢?看下面的代码,第一行代码我们尝试读取堆中的一个对象引用obj.fieldA并赋给引用o(fieldA也是一个对象时才会加上读屏障)。如果这时候对象在GC时被移动了,接下来JVM就会加上一个读屏障,这个屏障会把读出的指针更新到对象的新地址上,并且把堆里的这个指针“修正”到原本的字段里。这样就算GC把对象移动了,读屏障也会发现并修正指针,于是应用代码就永远都会持有更新后的有效指针,而且不需要STW。那么,JVM是如何判断对象被移动过呢?就是利用上面提到的颜色指针,如果指针是Bad Color,那么程序还不能往下执行,需要「slow path」,修正指针;如果指针是Good Color,那么正常往下执行即可:

图片

❝ 这个动作是不是非常像JDK并发中用到的CAS自旋?读取的值发现已经失效了,需要重新读取。而ZGC这里是之前持有的指针由于GC后失效了,需要通过读屏障修正指针。❞

后面3行代码都不需要加读屏障:Object p = o这行代码并没有从堆中读取数据;o.doSomething()也没有从堆中读取数据;obj.fieldB不是对象引用,而是原子类型。

正是因为Load Barriers的存在,所以会导致配置ZGC的应用的吞吐量会变低。官方的测试数据是需要多出额外4%的开销:

图片

那么,判断对象是Bad Color还是Good Color的依据是什么呢?就是根据上一段提到的Colored Pointers的4个颜色位。当加上读屏障时,根据对象指针中这4位的信息,就能知道当前对象是Bad/Good Color了。

❝ 「扩展阅读」:既然低42位指针可以支持4T内存,那么能否通过预约更多位给对象地址来达到支持更大内存的目的呢?答案肯定是不可以。因为目前主板地址总线最宽只有48bit,4位是颜色位,就只剩44位了,所以受限于目前的硬件,ZGC最大只能支持16T的内存,JDK13就把最大支持堆内存从4T扩大到了16T。❞

ZGC tuning

启用ZGC比较简单,设置JVM参数即可:-XX:+UnlockExperimentalVMOptions 「-XX:+UseZGC」。调优也并不难,因为ZGC调优参数并不多,远不像CMS那么复杂。它和G1一样,可以调优的参数都比较少,大部分工作JVM能很好的自动完成。下图所示是ZGC可以调优的参数:

图片

下面对部分参数进行更加详细的说明。

UseNUMA

ZGC默认是开启支持NUMA的,不过,如果JVM探测到系统绑定的是CPU子集,就会自动禁用NUMA。我们可以通过参数-XX:+UseNUMA显示启动,或者通过参数-XX:-UseNUMA显示禁用。如果运行在NUMA服务器上,并且设置-XX:+UseNUMA,那对性能提升是显而易见的。

  • UseLargePages

配置ZGC使用large page通常就会得到更好的性能,比如在吞吐量、延迟、启动时间等方面。而且没有明显的缺点,除了配置过程复杂一点。因为它需要root权限,这也是默认并没有开启使用large page的原因。

  • ConcGCThreads

ZGC是一个并发垃圾收集器,那么并发GC线程数就非常重要了。如果设置并发GC线程数越多,意味着应用线程数就会越少,这肯定是非常不利于应用系统稳定运行的。这个参数ZGC能自动设置,如果没有十足的把握。最好不要设置这个参数。

  • ParallelGCThreads

这是个并行线程数,与上一个参数ConcGCThreads有所不同,ConcGCThreads表示GC线程和应用线程「并发」执行时GC线程数量。而ParallelGCThreads表示GC时STW阶段的「并行」GC线程数量(例如第一阶段的Root扫描),这时候只有GC线程,没有应用线程。笔者这里解释了JVM中「并发和并行的区别」,也是JVM中比较容易理解错误的地方。

  • ZUncommit

掌握这个参数之前,我们先说一下JVM申请以及回收内存的行为。以前的垃圾回收器比如ParallelOldGC和CMS,只要JVM申请过的内存,即使发生了GC回收了很多内存空间,JVM也不会把这些内存归还给操作系统。这就会导致top命令中看到的RSS只会越来越高,而且一般都会超过Xmx的值(参考文章:)。

不过,默认情况下,ZGC是会把不再使用的内存归还给操作系统的。这对于那些比较注意内存占用情况的应用和服务器来说,是很有用的。这种行为可以通过JVM参数**-XX:-ZUncommit** 关闭。不过,无论怎么归还,JVM至少会保留Xms参数指定的内存大小,这就是说,当Xmx和Xms一样大的时候,这个参数就不起作用了。

和这个参数一起起作用的还有另一个参数:-「XX:ZUncommitDelay=sec」,默认300秒。这个参数表示不再使用的内存最多延迟多长时间才会被归还给操作系统。因为不再使用的内存不应该立即归还给操作系统,这样会造成频繁的归还和申请行为,所以通过这个参数来控制不再使用的内存需要经过多久的时间才归还给操作系统。

- END -

欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢:

已在知识星球更新源码解析如下:

最近更新《芋道 SpringBoot 2.X 入门》系列,已经 20 余篇,覆盖了 MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。

提供近 3W 行代码的 SpringBoot 示例,以及超 4W 行代码的电商微服务项目。

获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。

文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)
十一、ZGC垃圾回收器 Xlog:safepoint,classhisto*=trace,age*,gc*=info:file=/opt/logs/logs/gc-%t.log:time,tid,tags:filecount=5,filesize=50m 设置GC日志中的内容、格式、位置以及每个日志的大小。调大后GC变快,但会占用程序运行时的CPU资源,吞吐会受到影响。-XX:+UnlockDiagnosticVMOptions -XX:-ZProactive 是否启用主动回收,默认开启,这里的配置表示关闭。 阅读详情

相关推荐

GitHub 新手使用手册

理论说太多容易忘,来实践实践吧。

2501_90226046的博客 1053

牛逼了!JDK 16 ZGC 实现最大暂停时间不超过1ms

点击上方“芋道源码”,选择“设为星标”管她前浪,还是后浪?能浪的浪,才是好浪!每天 8:55 更新文章,每天掉亿点点头发...源码精品专栏原创 | Java 2020 超神之路,很肝~中...

芋艿V 338

【AI Agent 实战】OpenClaw 全面解析 + 全平台一键部署教程(本地 AI 智能体)

本文收录于 AI 智能体 & 自动化实战系列,手把手带你从零部署本地可控的 AI 执行助手关键词:OpenClaw、AI Agent、本地 AI 部署、自动化助手、Docker 部署

爱人爱己,风生水起 7907

垃圾回收算法、垃圾回收器CMS、G1、ZGC详解

当前虚拟机的垃圾收集都采用分代收集算法,根据对象存活周期的不同将内存分为几块。一般将Java堆分为新生代、老年代,这样就可根据各代特点选择合适的垃圾收集器。新生代中,每次收集都会有大量对象(99%)死去,所以选择复制算法,只需少量对象的复制成本就可完成每次对象的垃圾回收。老年代的存活几率是比较高的,所以选择“标记-清除”或“标记-整理”算法进行垃圾收集。注意,“标记-清除”和“标记-整理”算法比复制算法慢10倍以上。

earlybird_xiong的博客 3170

水文模型新手必看:用SWAT-CUP做参数率定,如何正确设置预热期、率定期和验证期?(附数据准备避坑指南)

本文详细介绍了使用SWAT-CUP进行水文模型参数率定的完整流程,重点解析了预热期、率定期和验证期的正确设置方法,并提供了数据准备的避坑指南。通过实操步骤和常见问题解决方案,帮助新手快速掌握SWAT-CUP参数率定的核心技巧,提升水文模型模拟精度。

weixin_26875109的博客 374

Winform从入门到精通(1)——Label(史上最全)

本篇文章是对专栏《winform控件从入门到精通》的详细介绍

qq_34059233的博客 4万+

Java 入门指南:JVM(Java虚拟机)垃圾回收机制 —— 新一代垃圾回收器 ZGC 收集器

ZGC(Z Garbage Collector) 是一种低延迟、可伸缩性强的垃圾回收器,是JVM 中的一项重要技术。ZGC的目标是 尽可能地减少垃圾回收对应用程序的停顿时间,并且可以处理大内存堆 。 它于Java 11版本中正式发布,适用于大内存低延迟服务的内存管理和回收,在 128G 的大堆下,最大停顿时间为 1.68 ms,停顿时间远胜于 G1 和 CMS。

热带鱼的技术博客 1784

基于STM32设计的智能水母投喂器(华为云IOT)_170

本项目利用STM32单片机控制各种传感器和水泵等设备,能够自动检测和调整水温和水质等参数,自动换水,自动供氧等等,充分满足了水母的养殖要求和需要。同时,根据水母喜欢的光环境,添加了RGB氛围灯,以及可以手动控制的喂食器等功能,提升了水母养殖的便利性和趣味性。

8808

JVM 垃圾收集器详解:CMS、G1 和 ZGC

垃圾回收(Garbage Collection, GC)是 Java 虚拟机(JVM)中一个至关重要的部分,尤其是在面对不同的业务场景时,选择合适的垃圾收集器(Garbage Collector, GC)对于优化 GC 性能至关重要。本文将详细介绍 JVM 中两大类垃圾收集器:分代收集器和分区收集器,并重点分析 CMS、G1 和 ZGC 这三种垃圾收集器的工作原理、优缺点及其适用场景

专注Java和MySQL领域知识分享 1932

QPrintPreviewDialog 打印预览使用实例

qt打印机预览实用demo

啊渊的专栏 3677

UNet 改进(19):与ASPP结合的图像分割模型

这个代码实现了一个改进版的UNet模型,在传统的UNet架构基础上,引入了ASPP模块来增强模型捕获多尺度上下文信息的能力。​​UNet主干网络​​:经典的编码器-解码器结构,带有跳跃连接​​ASPP模块​​:位于瓶颈层,用于提取多尺度特征。

2401_82355416的博客 878

Java GC:干掉 cms,zgc 才是未来

公众号后台回复“面试”,获取精品学习资料扫描下方海报了解专栏详情本文来源:公众号阿飞的博客《Java工程师面试突击(第3季)》重磅升级,由原来的70讲增至160讲,内容扩充一倍多,升级部...

石杉的架构笔记 549

倾斜摄影与地面激光点云融合高精度建模研究

本文研究了倾斜摄影与地面激光点云融合精细化建模技术,并通过相应的源代码实现了建模过程。该方法将倾斜摄影和激光扫描相结合,能够获得高精度的三维建模结果,为相关领域的研究和应用提供了有力支持。近年来,倾斜摄影和激光扫描技术的快速发展为高精度三维建模提供了新的机遇和挑战。本文针对倾斜摄影与地面激光点云融合建模这一前沿领域展开研究,旨在通过相应的源代码实现精细化的建模过程。同时,使用激光扫描仪进行地面激光扫描,获取地面的点云数据。经过数据融合和精细化建模处理后,我们获得了高精度的三维建模结果。

LpmShell的博客 1246

CMS G1垃圾收集器

CMS、G1、ZGC三款并发垃圾收集器,都提高了用户体验,其用户停顿时间也越来越小,但是相对应整个gc周期时间会变长

qq_44053632的博客 238

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

垃圾收集器-CMS

CMS垃圾收集器的优点是:高并发,低停顿,是HotSpot虚拟机上第一款真正意义的高并发垃圾收集器。后面G1和ZGC垃圾收集器都是对CMS垃圾收集器的一种演变。学好CMS垃圾收集器才是根本。

niankang2316的博客 429

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

java垃圾回收学习笔记二

栈,局部变量。 堆,new出来的对象。 随着内存越来越大,出现了越来越多的垃圾回收器 serial 单线程 parallel 多线程 也不是线程越多越好,多了cpu调度浪费资源 serial单线程,parallel多线程。CMS为并发,但他不是任何版本的jvm的默认选项,他是一款 承上启下的垃圾回收器。 CMS(主要是讲这个) 最重要的是:并发(垃圾回收线程与工作线程一起进行。边干活,边清理) 如果在并发的时候,突然有: 1)不是垃圾的又是垃圾了(没有被标记,但又被标记成垃圾,可以按照不是垃

qq_44969643的博客 286

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

JVM知识点汇总

jvm的知识体系 jvm分代算法 堆内存的逻辑分区 当创建一个对象首先会在eden区分配空间,如果分不开,直接进入老年代。 在eden区进行YGC,这时大多数的对象会被回收干掉,存活的对象放入s0,再次YGC ,包括eden区和s0,存活的对象会进入到s1区。之后再YGC,eden+s1->s0,回收一次年龄增加一岁,年龄足够大进入老年代。 垃圾回收器 STW(stop the world)停下用户线程,当触发垃圾回收机制,停下用户线程,然后单线程垃圾回收。回收后,程序继续运行,再

Sharpen__的博客 230

Java 14 发布!不使用"class"也能定义类了?还顺手要干掉Lombok!

2020 年 3 月 17 日,JDK/Java 14 正式 GA(General Available)。JDK14特性一览:JEP 305: Patt...

AI天才研究院 1万+

深入理解 JVM垃圾收集算法和垃圾收集器(一篇就够)

JVM垃圾收集算法和常见垃圾收集器原理分析

weixin_44991038的博客 1586

JVM调优--基础入门

GC基础

墨白千秋 461

JVM学习笔记 05 - 垃圾回收器

CMS 的全称是 Mostly Concurrent Mark and Sweep Garbage Collector(主要并发­标记­清除­垃圾收集器),它在年轻代使用复制算法,而对老年代使用标记-清除算法。你可以看到,在老年代阶段,比起 Mark-Sweep,它多了一个并发字样。CMS 的设计目标,是避免在老年代 GC 时出现长时间的卡顿(但它并不是一个老年代回收器)。如果你不希望有长时间的停顿,同时你的 CPU 资源也比较丰富,使用 CMS 是比较合适的。

Jomly Kellenda的博客 299

JVM垃圾收集算法与收集器

算法是什么? 复制算法copying: 新生代内: GC ROOTS 根节点–>扫描M0老内存区–>标记live对象–>复制–>新内存M1–>清空M0老内存区 场景:live少,dead多 为什么?反之 扫描+标记+复制+开辟新内存 增加成本 为什么放新生代? 答:新生代 eden from to 区域 内对象活动比较少 。 为什么效率高? 答:内存容量均等–&gt...

拿来主义的专栏 267

大厂面试题:有了G1还需要其他垃圾回收器吗?我教你怎么答

本篇文章我们主要来看下这两个高频的面试考题: G1 的回收原理是什么?为什么 G1 比传统 GC 回收性能好? 为什么 G1 如此完美仍然会有 ZGC? 我们在上次,简要的介绍了 CMS 垃圾回收器,下面我们简单回忆一下它的一个极端场景(而且是经常发生的场景)。 在发生 Minor GC 时,由于 Survivor 区已经放不下了,多出的对象只能提升(promotion)到老年代。但是此时老年代因为空间碎片的缘故,会发生 concurrent mode failure 的错误。这个时候,就需要降级为

weixin_51954021的博客 420

JVM(八)深入理解G1 GC(Garbage First)

探讨了G1垃圾回收器,一种在Java虚拟机中用于老年代垃圾回收的算法。G1的设计目标是减少停顿时间,适用于对延迟敏感的应用。它通过多个阶段实现垃圾回收,包括初始标记、并发标记、重新标记和并发清理。文章详细描述了这些阶段的工作原理和G1如何处理内存碎片问题。虽然G1能减少停顿时间,但它也有缺点,如内存碎片、需要预留空间处理浮动垃圾,以及更高的CPU资源消耗。随着新垃圾回收器如ZGC的出现,G1的使用正在逐渐减少,但对于运行在Java 8及以下版本的应用,G1的优化仍然重要。

m0_58466443的博客 2399
上一篇: 批处理框架 Spring Batch 这么强,你会用吗?
下一篇: 玩转 Java 动态编译,太秀了~!
公众号-芋道源码
博客等级 码龄10年 1631粉丝 377原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值