java ZGC 使用与调优
文章内容以翻译12为主。主要涉及如何使用和参数调优, 不涉及原理3
ZGC 全名 The Z Garbage Collector1, 是一个可伸缩的超低延迟垃圾回收器,主要目标是:
- 亚毫秒 级的最大暂停时间
- 暂停时间,不管堆、存活对象集、根对象集的大小怎么变化,都 不增长
- 支持的堆大小: 8MB - 16TB
ZGC 最开始作为实验特性出现在 JDK 11 中, 在 JDK 15 时达到生产可用水平。
简而言之, ZGC :
ZGC的核心是一个并发垃圾收集器,垃圾收集时,其它业务线程会继续执行,所以能极大地减小垃圾收集对应用程序响应时间的影响。
支持的平台
Platform | Supported | Since | Comment |
---|---|---|---|
Linux/x64 | ✓ | JDK 15 (实验特性 JDK11) | |
Linux/AArch64 | ✓ | JDK 15 (实验特性 JDK 13) | |
Linux/PPC | ✓ | JDK 17 | |
macOS/x64 | ✓ | JDK 15 (实验特性 JDK 14) | |
macOS/AArch64 | ✓ | JDK 17 | |
Windows/x64 | ✓ | JDK 15 (实验特性 JDK 14) | Windows 1803 (Windows 10 或 Windows Server 2019) 以上. |
Windows/AArch64 | ✓ | JDK 16 |
快速使用
添加如下 java 选项即可启用ZGC:
1 | -XX:+UseZGC -Xmx<size> -Xlog:gc |
如果需要更多gc的详细日志:
1 | -XX:+UseZGC -Xmx<size> -Xlog:gc* |
配置和调优
可用选项概览
ZGC 可以使用的 JVM 选项 :
通用 GC 选项 | ZGC 选项 | ZGC 诊断选项 (-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 |
启用 ZGC
使用 -XX:+UseZGC
选项启用 ZGC.
设置堆空间大小
最大堆内存 (-Xmx<size>
),对ZGC来说是最重要的调优选项。设置合理的堆内存大小, 保证有足够的空间存放存活的对象(live-set)以及 GC运行时还有足够的空间拿分配。堆空间分配多大, 取决于应用的内存分配频率和存活对象大小。通常来说,给ZGC的内存越大越好,但是浪费内存也不太好。所以最好根据内存使用情况和GC频率来调整。
设置GC并发线程数
第二个值得关注的选项是GC并发线程数( -XX:ConcGCThreads=<number>
)。ZGC会启发式的自动选择线程数,多数情况下自动选择线程数就可以了, 但是有时候根据应用的特点, 可能需要调整。 这个选项,本质上是指定了GC占用的CPU时间, 设置过大就会占用应用的CPU时间;如果太小,应用产生垃圾对象的速度又会超过GC速度。
注意! 如果系统对响应时间要求高, 那最好不要过度压榨机器, cpu使用率最好不要超过70%。
返还未使用内存给操作系统
默认情况下,ZGC 会返还未使用的内存给操作系统。 这个特性对于那些关注内存占用大小的应用和环境比较有用。通过-XX:-ZUncommit
可禁用些特性。当然,返还操作不会让堆内存小于设置的最小堆大小(-Xms
)。 所以如果-Xms
和-Xmx
一样的话, 这个特性也就不起作用了。
返还延迟使用-XX:ZUncommitDelay=<seconds>
设置, 默认是300秒。此选项指定内存多久未被使用后, 会返还给操作系统。
注意! Linux上, 返还内存需要 fallocate(2)
加 FALLOC_FL_PUNCH_HOLE
支持, 需要内核版本 3.5 ( tmpfs) 、 4.3 ( hugetlbfs)以上.
Linux 上启用大内存页
一般配置ZGC使用大内存页,会获得更好的性能(在吞吐量、延迟、启动时间方面),而且几乎没有缺点, 只是设置起来稍微有点复杂。而且安装过程需要root权限,所以没有默认启用。
Linux/x86上, 大内存页的大小是2MB.
假设Java堆内存为 16G .那就需要 16G / 2M = 8192 个大内存页.
首先, 分配至少16G(8192页)内存给大内存页池。分配的大页池一定要大于堆内存, 因为除了堆内存,JVM的其它部分也要使用大页来处理各种内存数据结构(code heap,marking bitmaps 等 )。 示例中将分配9216页(18G),可以允许java2G的非堆内存使用大页。
配置操作系统大页池为需要的数量 (需要root权限):
1 | $ echo 9216 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages |
注意:光上面这个命令不能保证配置成功,因为内核可能没有足够的空余大页。同时,系统可能也需要花一些时间来处理。在继续后面的步骤之前,先检查分配给大页池的数量,以确保设置成功并已完成。
1 | $ cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages |
注意: 如果Linux kernel >= 4.14 可跳过下面这个步骤(挂载一个hugetlbfs文件系统)。对于之间的内核版本, ZGC需要通过hugetlbfs文件系统, 来访问大内存页。
挂载hugetlbfs文件系统 (需要root权限) ,并让运行JVM的用户可以访问它。 (例子中, 假设用户的uid是123).
1 | $ mkdir /hugepages |
添加 -XX:+UseLargePages
选项,启动 JVM
1 | $ java -XX:+UseZGC -Xms16G -Xmx16G -XX:+UseLargePages |
如果有多个可访问的hugetlbfs文件系统,需要用-XX:AllocateHeapAt
选项来指定路径, 假设我们想用的hugetlbfs文件系统挂载路径是/hugepages
:
1 | $ java -XX:+UseZGC -Xms16G -Xmx16G -XX:+UseLargePages -XX:AllocateHeapAt=/hugepages |
注意! 大页池的配置和hugetlbfs文件系统的挂载不是持久的,重启失效。如何持久化配置, 可能需要自行搜索一下。
Linux 上透明启用大内存页 – 不建议使用
相对于使用显式大页(如上所述)的另一种选择是透明使用大页。对于延迟敏感的应用程序,通常不建议透明使用
大页,因为这会导致不必要的延迟峰值。然而,它可能值得尝试一下,看看它是否/如何影响您的工作负载。
但要注意,你的过程可能会有所不同。
启用NUMA4支持
NUMA 非统一内存访问架构(英语:Non-uniform memory access,简称NUMA)是一种为多处理器的电脑设计的内存架构,内存访问时间取决于内存相对于处理器的位置。ZGC支持NUMA,并默认开启此特性。.但是,如果JVM检测到它只使用单个NUMA节点上的内存,它将自动被禁用。一般不需要关心此设置, 如果想显示的指定,可以通过 -XX:+UseNUMA
或 -XX:-UseNUMA
选项来开启或者关闭(同一个选项的+
、-
分别表示开启、关闭)。
当运行在NUMA机器上时(例如一个多插槽x86机器),启用NUMA支持通常会带来显著的性能提升。
启用GC日志
GC 日志使用如下选项开启:
1 | -Xlog:<tag set>,[<tag set>, ...]:<log file> |
有关此选项的信息和帮助:
1 | -Xlog:help |
启用基本日志(每个GC输出一行):
1 | -Xlog:gc:gc.log |
启用对调优/性能分析有用的GC日志:
1 | -Xlog:gc*:gc.log |
其中gc*
表示日志打印包含gc
的所有标记组合,:gc.log
表示将日志写入名为’ gc.log ‘的文件。
参考资料
- 1.OpenJDK 官方 wiki https://wiki.openjdk.java.net/display/zgc/Main ↩
- 2.Oracle官方javase 文档GC调优指南 Oracle: HotSpot Virtual Machine Garbage Collection Tuning Guide ↩
- 3.F叔的学习笔记 ZGC 笔记:Colored Pointers ↩
- 4.NUMA Wiki https://zh.wikipedia.org/zh-hans/非均匀访存模型 ↩