首页 > 其他分享 >JVM-垃圾回收器-ZGC

JVM-垃圾回收器-ZGC

时间:2024-06-15 17:58:46浏览次数:26  
标签:标记 对象 XX GC 垃圾 JVM ZGC 内存

  1. 新一代垃圾回收器ZGC的探索与实践 - 美团技术团队
  2. Main - Main - OpenJDK Wiki

介绍

        ZGC(Z Garbage Collector) 是一款性能比 G1 更加优秀的垃圾收集器。ZGC 第一次出现是在  JDK 11 中以实验性的特性引入,这也是 JDK 11 中最大的亮点。在 JDK 15 中 ZGC 不再是实验功能,可以正式投入生产使用了,使用 –XX:+UseZGC 可以启用 ZGC。

特征

  1. 停顿时间(STW)不超过10ms(JDK16是不超过1ms),且不会随着堆的大小增加而增加

      G1 300ms

  1. 理论上最大支持 16TB 的大堆,最小支持 8MB 的小堆。2048 分区,堆128G还是负担比较重
  2. 跟 G1 相比,对应用程序吞吐量的影响小于15%,吞吐量,通过扩容解决

目标

主要目标:巩固老大地址、卷其他语言!

  1. 抢C++的市场
  2. 防止被go语言等抢市场

ZGC的案例介绍

阿里(借鉴ZGC优化自己JVM)

美团(规则平台等)

58(Hbase平台)

腾讯(在线交互、竟价广告、量化交易等)

华为(毕昇JDK、大数据项目) 

堆空间分页模型(无分代)

将内存分为三种类型的页面

  1. 小型Region(Small Region):容量固定为2MB, 用于放置小于256KB的小对象。
  2. 中型Region(Medium Region):容量固定为32MB, 用于放置大于等于256KB但小于4MB的对象。
  3. 大型Region(Large Region):容量不固定, 可以动态变化, 但必须为2MB的整数倍, 用于放置4MB或以上的大对象。 和操作系统有关

页面类型

页面大小

页面内对象的大小

页面内对象对齐的粒度

小页面

2MB

小于等于256KB

MinObjectAlignmentInBytes

中页面

32MB

在256KB和4MB之间

4KB

大页面

X*MB,受操作系统控制

大于4MB

2MB

ZGC对于不同页面回收的策略也不同。简单地说,小Region优先回收;中Region和大Region则尽量不回收 

 为什么这么设计?

Linux Kernel 2.6引入的标准大页(huge page)

标准大页(huge page)是Linux Kernel 2.6引入的目的是通过使用大页内存来取代传统的4KB内存页面,以适应越来越大的系统内存,让操作系统可以支持现代硬件架构的大页面容量功能

 ZGC的内存布局

        应用程序创建对象时,首先在堆空间申请一个虚拟地址,但该虚拟地址并不会映射到真正的物理地址。ZGC同时会为该对象在M0、M1和Remapped地址空间分别申请一个虚拟地址,且这三个虚拟地址对应同一个物理地址,但这三个空间在同一时间有且只有一个空间有效。ZGC之所以设置三个虚拟地址空间,是因为它使用“空间换时间”思想,去降低GC停顿时间。“空间换时间”中的空间是虚拟空间,而不是真正的物理空间

虚拟内存映射

NUMA

统一内存访问UMA:

  • 在x86架构中,内存没有整合进CPU,需要总线来访问
  • 任何CPU访问内存的速度都是一致的,没有差异,称为统一内存访问Uniform Memor Access, UMA)
  • 当所有核都链接到一块内存上时,访问内存中任何一个区域的时间都相同

NUMA:

核访问与自己直接相连的内存区域,比访问其它区域快的多,因为访问其它区域需要通过另外一个芯片,因此被称为非一致性内存访问系统NUMA(Nonuniform Memory Access)

        UMA系统中因为核直接和内存相连,任意一个核都能访问内存中的任何地址,因此当数据存储在内存中不同位置时,UMA系统存取指令和数据更快。NUMA系统中因为内存可以连接到不同的内存上,因此具有更好的内存扩展性。

        因为在NUMA系统中想要存取不同内存上的数据时,需要核心直接交互才能实现,跨NUMA会导致几纳秒的时间浪费,因此如果程序对性能比较敏感需要将程序绑定到指定的NUMA上,以此来避免不同NUMA之间核的交互

ZGC为什么那么快?

分代模型和分区模型

•低延迟:

        ZGC的分页模型允许并发地处理内存分配和回收操作,从而减少了垃圾收集的停顿时间。相比之下,分代模型需要在不同代之间进行对象的复制或移动,可能会导致更长的停顿时间。

•内存利用率高:

        ZGC的分页模型可以动态地调整页的大小,以适应不同大小的对象。这样可以提高内存的利用率,减少内存碎片的产生。而分代模型中,不同代的内存空间是固定的,可能会导致内存碎片的问题。

•可伸缩性:

        ZGC的分页模型允许将堆内存划分为多个页区,并且每个页区都有独立的垃圾收集线程。这样可以实现垃圾收集的并行性,提高系统的可伸缩性和吞吐量。而分代模型中,不同代的垃圾收集是串行或并发-串行的,可能无法充分利用多核处理器的性能。

•适应大内存堆:

        ZGC的分页模型可以有效地管理大内存堆。它可以根据需要动态地增加或减少页的数量,以适应大内存堆的需求。而分代模型中,不同代的内存空间是固定的,无法有效地管理大内存堆。

GC标记信息位置的变化

        传统垃圾回收器通过扫描堆中的对象(扫描堆空间是很慢的),根据对象头中的可达性标记信息,来确定对象是否应该被回收。

        ZGC不直接依赖于对象头中的信息来进行垃圾回收决策,而是把GC信息存在内存引用地址上。GC时通过扫描栈上的内存引用指针来确定对象的引用关系和可达性,从而来判断对象是否应该被回收。       

垃圾回收流程

标记阶段(标识垃圾)
转移阶段(对象复制或移动)

初始阶段:在ZGC初始化之后,此时地址视图为Remapped,程序正常运行,在内存中分配对象,满足一定条件后垃圾回收启动。

初始标记:初始标记只需要扫描所有GC Roots,其处理时间和GC Roots的数量成正比,停顿时间不会随着堆的大小或者活跃对象的大小而增加。

并发标记:扫描剩余的所有对象,这个处理时间比较长,所以走并发,业务线程与GC线程同时运行。但是这个阶段会产生漏标问题。

基于上一步的绿色节点开始并发标记:所有访问到的活对象都标记为绿色,指针也是绿色

再标记:主要处理漏标对象,通过SATB算法解决(G1中的解决漏标的方案)

主要解决并发标记过程中的漏标问题,活的对象和指针仍然是绿色,可以发现,再标记之后,仍然是蓝色的对象就是垃圾对象

  1. 并发转移准备:分析最有价值GC分页哪些区域有垃圾,哪些需要回收等等
  2. 初始转移:转移初始标记的存活对象同时做对象重定位,初始标记的对象,就是初始转移的对象,GC ROOTS

并发转移:对转移并发标记的存活对象做转移,经过并发标记和再标记调整之后的对象,就是并发转移的对象

在两次GC中间业务线程如何访问没有做完重定位的对象?

参数

If you're trying out ZGC for the first time, start by using the following GC options:

-XX:+UseZGC -XX:+ZGenerational -Xmx<size> -Xlog:gc

For more detailed logging, use the following options:

-XX:+UseZGC -XX:+ZGenerational -Xmx<size> -Xlog:gc*

堆大小:Xmx。当分配速率过高,超过回收速率,造成堆内存不够时,会触发 Allocation Stall,这类 Stall 会减缓当前的用户线程。因此,当我们在GC日志中看到 Allocation Stall,通常可以认为堆空间偏小或者 concurrent gc threads 数偏小。

GC 触发时机:ZAllocationSpikeTolerance, ZCollectionInterval。ZAllocationSpikeTolerance 用来估算当前的堆内存分配速率,在当前剩余的堆内存下,ZAllocationSpikeTolerance 越大,估算的达到 OOM 的时间越快,ZGC 就会更早地进行触发 GC。ZCollectionInterval 用来指定 GC 发生的间隔,以秒为单位触发 GC。

GC 线程:ParallelGCThreads, ConcGCThreads。ParallelGCThreads 是设置 STW 任务的 GC 线程数目,默认为 CPU 个数的 60%;ConcGCThreads 是并发阶段 GC 线程的数目,默认为 CPU 个数的 12.5%。增加 GC 线程数目,可以加快 GC 完成任务,减少各个阶段的时间,但也会增加 CPU 的抢占开销,可根据生产情况调整。

General GC Options

ZGC Options

ZGC Diagnostic Options (-XX:+UnlockDiagnosticVMOptions)

-XX:MinHeapSize, -Xms

-XX:InitialHeapSize, -Xms

-XX:MaxHeapSize, -Xmx

-XX:SoftMaxHeapSize

-XX:ConcGCThreads

-XX:ParallelGCThreads

-XX:UseDynamicNumberOfGCThreads

-XX:UseLargePages

-XX:UseTransparentHugePages

-XX:UseNUMA

-XX:SoftRefLRUPolicyMSPerMB

-XX:AllocateHeapAt

-XX:ZAllocationSpikeTolerance

-XX:ZCollectionInterval

-XX:ZFragmentationLimit

-XX:ZMarkStackSpaceLimit

-XX:ZProactive

-XX:ZUncommit

-XX:ZUncommitDelay

-XX:ZStatisticsInterval

-XX:ZVerifyForwarding

-XX:ZVerifyMarking

-XX:ZVerifyObjects

-XX:ZVerifyRoots

-XX:ZVerifyViews

-XX:ZYoungGCThreads

-XX:ZOldGCThreads

-XX:ZBufferStoreBarriers

 

标签:标记,对象,XX,GC,垃圾,JVM,ZGC,内存
From: https://blog.csdn.net/qq_26594041/article/details/139382160

相关文章

  • Python中的垃圾回收机制
    1.引言在现代编程中,垃圾回收是确保程序稳定运行的关键技术之一。Python,作为一种高级编程语言,拥有一套成熟的垃圾回收机制,它在背后默默地管理着内存,确保程序不会因为内存泄漏而崩溃。本文将深入探讨Python中的垃圾回收机制,以及它如何影响我们的代码。2.Python内存管理基......
  • JVM 调优和深入了解
    调优的原则1、大多数的java应用不需要GC调优2、大部分需要GC调优的的,不是参数问题,是代码问题3、在实际使用中,分析GC情况优化代码比优化GC参数要多得多;4、GC调优是最后的手目的GC的时间够小GC的次数够少发生FullGC的周期足够的长,时间合理,最好是不发生......
  • JVM之编写高效优雅 Java 程序
    面向对象01、构造器参数太多怎么办?如果参数很多,会导致构造方法非常多,拓展性差,代码难编写,且难以看懂。用JavaBeans模式,get和set一行构造编程多行代码实现,需要使用额外机制确保一致性和线程安全。用builder模式,1、5个或者5个以上的成员变量2、参数不多,但是在未来,......
  • JVM类加载机制
    类加载机制概述类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)7个阶段。其中验证、准备、解析3个部分统称为连接(Link)。初始化的单例......
  • jvm调优工具和调优策略
    JDK为我们提供的jvm工具命令行工具jps、jstat、jinfo、jmap、jhat、jstack可视化工具JMX、Jconsole、visualvm生产服务器推荐开启-XX:-HeapDumpOnOutOfMemoryError默认关闭,建议开启,在java.lang.OutOfMemoryError异常出现时,输出一个dump.core文件,记录当时的堆内存快......
  • JVM垃圾回收算法和垃圾回收器
    垃圾回收算法复制算法(Copying)将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。这样使得每次都是对整个半区进行内存回收,内存分配时也就不用考虑内存碎片等复杂情......
  • JVM中的对象
    虚拟机中的对象对象的分配虚拟机遇到一条new指令时:根据new的参数是否能在常量池中定位到一个类的符号引用,如果没有,说明还未定义该类,抛出ClassNotFoundException1)检查加载先执行相应的类加载过程。如果没有,则进行类加载2)分配内存根据方法区的信息确定为该类分配的内存空......
  • JVM垃圾回收策略机制和算法
    判断对象的存活引用计数法给对象添加一个引用计数器,当对象增加一个引用时计数器加1,引用失效时计数器减1。引用计数为0的对象可被回收。(Python在用,但主流虚拟机没有使用)优点:快,方便,实现简单。缺陷:对象相互引用时(A.instance=B同时B.instance=A),很难判断对象是否该回收。......
  • JVM运行时数据区(线程相关)
    一、JVM运行时数据区JVM运行时数据区是一个抽象概念,主要依赖于寄存器、高速缓存、主内存几个部分组成。计算机运行=指令+数据,指令用于执行方法,数据用于指向存放的数据和对象。虚拟机栈---用于执行java方法本地方法栈---执行本地方法(通常时c语言实现的)程序计数......
  • 基于SpringBoot+Vue+uniapp微信小程序的垃圾分类系统的详细设计和实现(源码+lw+部署文
    文章目录前言详细视频演示项目运行截图技术框架后端采用SpringBoot框架前端框架Vue可行性分析系统测试系统测试的目的系统功能测试数据库表设计代码参考数据库脚本为什么选择我?获取源码前言......