07_Z Garbage Collector (ZGC)

Z垃圾收集器(ZGC)是一种可扩展的低延迟垃圾收集器。ZGC可以在不超过一毫秒的情况下并发执行所有昂贵的工作,而不会停止应用程序线程的执行。它适用于需要低延迟的应用程序。暂停时间与正在使用的堆大小无关。ZGC适用于从几百兆字节到16TB的堆大小。

ZGC被设计为自适应且需要最小的手动配置。在Java程序执行期间,ZGC通过调整代大小、扩展GC线程数量和调整老年对象阈值动态适应工作负载。主要调优参数是增加最大堆大小。

ZGC有两个版本:新版分代版和传统非分代版。非分代ZGC是较旧的版本,它不利用代来优化运行时特性。鼓励用户转向使用更新的分代式ZGC。

使用命令行选项 -XX:+UseZGC -XX:+ZGenerational 可启用分代式ZGC。

使用命令行选项 -XX:+UseZGC 可启用非分代式ZGC。

设置堆大小

ZGC最重要的调优选项是设置最大堆大小,可以使用 -Xmx 命令行选项进行设置。由于ZGC是一种并发收集器,必须选择一个最大堆大小,使得堆可以容纳应用程序的存活集,并且在GC运行时有足够的余地来处理分配。所需的余地大小很大程度上取决于分配速率和应用程序的存活集大小。一般来说,给ZGC更多的内存越好。但同时,浪费内存是不可取的,因此关键在于找到内存使用和GC运行频率之间的平衡。

ZGC还有另一个与堆大小相关的命令行选项,名为 -XX:SoftMaxHeapSize。它可以用于设置Java堆能够增长到多大的软限制。ZGC会努力保持不超过这个限制,但仍然允许增长到最大堆大小以上。只有在需要防止Java应用程序停滞等待GC回收内存时,ZGC才会使用超过软限制的内存。例如,使用命令行选项 -Xmx5g -XX:SoftMaxHeapSize=4g 时,ZGC将以4GB作为其启发式算法的限制,但如果无法将堆大小保持在4GB以下,则仍然允许暂时使用高达5GB的内存。

将未使用的内存返回到操作系统

默认情况下,ZGC会释放未使用的内存,并将其返还给操作系统。这对于关注内存占用的应用程序和环境非常有用,但可能会对Java线程的延迟产生负面影响。您可以使用命令行选项 -XX:-ZUncommit 来禁用此功能。此外,不会释放内存以使堆大小缩小到低于最小堆大小(-Xms)。这意味着如果将最小堆大小(-Xms)配置为等于最大堆大小(-Xmx),则此功能将被隐式禁用。

您可以使用 -XX:ZUncommitDelay=<seconds>(默认值为300秒)来配置取消提交延迟。该延迟指定了内存在未使用多长时间后才能进行取消提交。


注意:允许垃圾回收在应用程序运行时提交和取消提交内存可能会对Java线程的延迟产生负面影响。如果极低的延迟是使用ZGC的主要原因,请考虑将 -Xmx 和 -Xms 设置为相同的值,并使用 -XX:+AlwaysPreTouch 在应用程序启动之前预取内存页。

使用大页

将ZGC配置为使用大页通常会带来更好的性能(以吞吐量、延迟和启动时间为代价),并且几乎没有实质性的劣势,除了设置稍微复杂一些。设置过程通常需要 root 权限,这就是为什么默认情况下它是禁用的。

在 Linux 上启用大页面

在Linux x86系统上,大页面(也称为“超大页面”)的大小为2MB。

假设您希望使用16GB的Java堆。这意味着您需要 16GB / 2MB = 8192 个超大页面。

堆至少需要16GB(8192页面)的内存分配给超大页面池。堆以及JVM的其他部分将使用大页面来存储各种内部数据结构(如代码堆和标记位图)。在此示例中,您将保留9216个页面(18GB),以便允许额外的2GB非Java堆内存分配使用大页。

配置系统的超大页面池以拥有所需数量的页面(需要root权限):

$ echo 9216 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages

请注意,如果内核无法找到足够的空闲超大页面来满足请求,则以上命令无法成功执行。此外,请注意,内核可能需要一些时间来处理请求。在继续之前,请检查分配给池的超大页面数量,以确保请求成功并已完成:

$ cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages

9216

在 Linux 上实现透明的大页面

与之前描述的显式使用大页不同的另一种选择是使用透明大页(transparent huge pages)。通常不建议对延迟敏感的应用程序使用透明大页,因为它往往会导致意外的延迟波动。然而,值得尝试一下,观察您的工作负载是否受到影响。

注意:在Linux系统上,启用透明大页的情况下使用ZGC需要内核版本大于等于4.7。

使用以下选项在虚拟机中启用透明大页:

-XX:+UseLargePages -XX:+UseTransparentHugePages

这些选项告诉JVM对其映射的内存发出madvise(...,MADV_HUGEPAGE)调用,这在使用透明大页的madvise模式下非常有用。

要启用透明大页,还需要通过启用madvise模式来配置内核。

$ echo madvise > /sys/kernel/mm/transparent_hugepage/enabled

ZGC使用shmem大页来管理堆内存,因此还需要配置以下内核设置:

$ echo advise > /sys/kernel/mm/transparent_hugepage/shmem_enabled

在比较不同GC的性能时,检查这些内核设置非常重要。一些Linux发行版会强制将/sys/kernel/mm/transparent_hugepage/enabled配置为always以启用私有页面的透明大页,同时将/sys/kernel/mm/transparent_hugepage/shmem_enabled保持默认值never。在这种情况下,除了ZGC外,所有GC都将使用透明大页来管理堆。更多信息请参阅《透明大页支持》(Transparent Hugepage Support)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值