Java中ZGC通过自动调整堆大小优化内存利用率


在这篇博客文章中,我们介绍了ZGC中堆大小调整的创新自动化策略,利用CPU利用率作为“调优旋钮”来优化性能和内存使用。

有效的堆大小管理对于优化Java应用程序的内存利用率和性能至关重要。

然而,手动配置堆大小限制带来了挑战。首先,它既费时又低效,而且还很难考虑到内存使用的动态变化。

确定理想的堆大小是很复杂的,特别是考虑到不同的参数,如硬件配置。
我们的研究显示,不同机器之间的堆大小不同,没有明显的模式,即使在同一台机器上有不同的核心配置。这些变化使得堆的大小必须有很大的变化,突出了人工设置堆大小的局限性。

引入自动化的堆设置
我们确定堆大小的方法是基于CPU利用率的。
我们不是通过设置堆的大小来控制一个应用程序应该做多少GC,而是让GC使用CPU,与应用程序的CPU使用率成比例(用户定义)。

因此,如果应用程序的CPU使用量增加--因此通常是它的分配率--那么用于GC的CPU也会增加。

工作原理
在ZGC中实现自适应的堆大小是利用现有的软最大堆大小限制。这个限制会触发垃圾收集而不引起停顿,直到它达到Xmx(最大堆)参数。

在每个垃圾收集周期结束时,软最大堆被调整以满足程序员设定的目标GC CPU开销。

GC的CPU开销是通过比较应用程序线程和GC线程花费的时间来衡量的。

我们在ZGC中实现了自适应堆的大小,这是因为它作为一个完全并发的垃圾收集器的独特性质。

有了ZGC,垃圾收集的暂停时间非常小,而且收集器永远不会在关键路径上。这使我们能够自信地缩小堆的大小而不对延迟产生任何重大影响。

性能评估
为了评估自动堆调整的影响,我们用多个GC目标(5%、10%、15%和20%)对各种基准进行了测试。

调整GC目标会显著影响内存使用,较高会减少应用程序的内存使用,较低会增加内存使用。

执行时间一般不受影响,但特定的基准可能显示出改善或退化。

内存使用量和能耗之间的关系很复杂,较高的GC目标会因为较高的CPU使用率而增加能耗。
然而,在过度承诺的CPU环境中,减少内存的使用可以导致更低的能耗。

自适应方法对延迟有积极或中性的影响,在CPU密集型的工作负载中会减少延迟。

结论
自动设置堆大小策略为人工设置堆大小的挑战提供了一个积极的解决方案。

通过赋予开发人员对垃圾收集的CPU利用率的控制权,我们不再需要跟踪内存使用模式并手动确定堆的大小。

这种方法减少了内存浪费和简化了开发过程。

通过接受自动化的堆大小,开发人员可以释放其应用程序的全部潜力,同时享受简化的内存管理。