Java实时应用程序的垂直缩放



通过GC调优,我成功地获得了实时java应用程序的性能,并避免了可识别的GC暂停。但是,这可以容纳大约20 GB的堆空间。

硬件成本的降低使100GB的RAM机器也变得负担得起。但是,由于GC暂停,Java仍然存在,更高的堆大小(如50GB)可能会让您经常陷入噩梦。

我知道有诸如堆外和分布式堆之类的选项。但是,堆外有一个缺点,即分散堆一方面增加了维护成本。此外,在分布式堆中,您实际上并没有完全利用RAM(比如64GB),而现在RAM作为商品越来越普遍。

因此,为了充分利用RAM的潜力,Java应用程序的垂直扩展有哪些好的解决方案?

我正在开发一个名为Banana的原始集合库。Banana正好解决了这些问题。它很快支持LinkedLists、HashMaps和可能的其他数据结构,而不需要保留N个对象的开销。基本上,整个存储可以在一个int[]数组(或多个)内。

虽然我还没有正式发布它,但它的大部分都经过了良好的测试,我已经在144GB RAM的服务器上成功运行了它,在没有任何GC暂停的情况下保持了快速一致的性能。

查看这个哈希图基准测试,了解如何使用Banana存储数据以及它的垂直扩展能力。

https://github.com/omry/banana/wiki/Long-to-fixed-size-object-benchmark

有关详细信息,请参阅wiki。

垃圾回收时间是堆中活动对象数量的函数。这意味着,如果你的分配率很高,但活动对象的数量总是很低,你可以使用你想要的RAM,而不会有明显的停顿。

对于槽式收集器(-XX:+UseParallelOldGC),这种说法尤其正确。

如果您使用CMS,那么您可能需要检查其增量模式(-XX:+CMSIncrementalMode)。它将触发较小的CMS周期来清理堆的一小部分,同时利用硬件并且没有STW暂停。

如果CMS不是一个选项,那么您应该看看G1(-XX:+UseG1GC),它是一个为大型堆设计的新垃圾回收器。其原理是:在每个循环中只清理堆的几个区域,但要确保这些区域包含大量死对象(快速获得)。

希望能有所帮助!

来源:

  • http://www.infoq.com/articles/G1-One-Garbage-Collector-To-Rule-Them-All
  • http://jvm-options.tech.xebia.fr/

我对JVM的堆大小进行了一些研究。您可以在此处和此处阅读更多详细信息。

主要结论:年轻气相色谱停顿有常量和变量两个组成部分。

恒定组件取决于旧的空间大小,对于64GiB,我预计它是80ms-120ms(取决于硬件)。

可变分量取决于对象在年轻空间中的生存(因此它从一个集合变为另一个集合)。它确实是特定于应用程序的,但您通常可以通过减少年轻空间来减少它(以更频繁的暂停为代价)。

在你的情况下,4 GiB的年轻空间,你有500毫秒。假设可变分量为400ms,如果将年轻空间减少到1GiB,则应该有约200ms的暂停(但每秒2次)。

另一种方法是使用更多的CPU内核,年轻的GC并行性非常好。

最新更新