简体   繁体   English

Java实时应用程序的垂直扩展

[英]Vertical Scaling of Java real-time application

With GC tuning I am successfully able to get performance for real-time java applications and avoiding recognizable GC pauses. 通过GC调优,我成功地获得了实时Java应用程序的性能,并避免了可识别的GC暂停。 But, this holds good up to ~20 GB of heap space. 但是,这可以容纳大约20 GB的堆空间。

Decrease in the hardware cost has made even 100GB of RAM machines affordable. 硬件成本的降低使得即使是100GB的RAM机也能负担得起。 But, still with Java due to GC pauses, higher heap sizes like 50 GB can send you into nightmare at regular times. 但是,由于GC暂停,仍然使用Java,更高的堆大小(如50 GB)会让您经常陷入噩梦。

I understand that there are options like off-heap and distributed-heap. 我知道有像堆外和分布式堆这样的选项。 But, off-heap has a disadvantage of se/derialization and distributed-heap on the hand increases maintenance cost. 但是,堆外具有se / derial的缺点,并且手上的分布式堆增加了维护成本。 Further, in distributed-heap you are actually not fully utilizing RAM (say 64 GB) which these days are becoming common as commodity. 此外,在分布式堆中,您实际上并没有充分利用RAM(比如64 GB),而这些日子正变得越来越普遍。

Therefore, to fully utilize the potential of RAM, what are the good solutions for vertical scaling of Java applications? 因此,为了充分利用RAM的潜力,Java应用程序的垂直扩展有哪些好的解决方案?

I am working on a primitive collections library called Banana . 我正在研究一个名为Banana的原始集合库。 Banana addresses those exact issues. 香蕉解决了这些问题。 It supports LinkedLists, HashMaps and possibly other data structures soon without the overhead of keeping N objects. 它很快就支持LinkedLists,HashMaps和其他可能的数据结构,而不需要保留N个对象的开销。 basically - the entire storage can be inside an int[] array (or many). 基本上 - 整个存储可以在int []数组(或许多)中。

While I did not yet officially released it, most of it is well tested and I have already ran it successfully on servers with 144GB of RAM, maintaining fast and consistent performance without any GC pauses. 虽然我还没有正式发布它,但大部分都经过了很好的测试,我已经在拥有144GB内存的服务器上成功运行它,在没有任何GC暂停的情况下保持快速一致的性能。

Check out this hash-map benchmark to get an idea on how to use Banana to store data and how well it scales vertically. 查看哈希映射基准,以了解如何使用Banana存储数据以及它如何垂直扩展。

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

See the wiki for more info. 有关更多信息,请参阅维基

Garbage Collection time is a function of the number of live objects in your heap. 垃圾收集时间是堆中活动对象数量的函数。 This means that if your allocation rate is very high but the number of live objects is always low, you can use as much RAM as you want without having significant pauses. 这意味着如果您的分配率非常高但活动对象的数量总是很少,您可以使用尽可能多的RAM而不会有明显的暂停。

This statement is particularly true with the Troughput Collector ( -XX:+UseParallelOldGC ). 对于Troughput收集器( -XX:+UseParallelOldGC ),此声明尤其如此。

If you use CMS, then you probably want to check its incremental mode ( -XX:+CMSIncrementalMode ). 如果您使用CMS,则可能需要检查其增量模式( -XX:+CMSIncrementalMode )。 It will trigger smaller CMS cycles to clean a smaller fraction of your heap, while leveraging your hardware and without STW pauses. 它将触发较小的CMS周期来清理堆的一小部分,同时利用硬件并且不会出现STW暂停。

If CMS is not an option, then you should have a look at G1 ( -XX:+UseG1GC ), which is a new Garbage Collector designed for large heaps. 如果CMS不是一个选项,那么你应该看看G1( -XX:+UseG1GC ),它是一个专为大堆设计的新垃圾收集器。 The principle is : clean only several regions of the heap at each cycle but make sure these regions contains a lot of dead objects (quick gains). 原则是:在每个循环中只清理堆的几个区域,但要确保这些区域包含大量死对象(快速增益)。

Hope that helps ! 希望有所帮助!

Sources : 资料来源:

I did some research on scaling heap size of JVM. 我做了一些关于扩展JVM堆大小的研究。 You can read more details here and here . 您可以在此处此处阅读更多详细信息。

Main conclusion: young GC pause have two components constant and variable. 主要结论:年轻的GC暂停有两个组件恒定和可变。

Constant component depends on old space size and for 64GiB, I expect it to be 80ms-120ms (dependent on hardware). 常量组件取决于旧的空间大小,对于64GiB,我预计它是80ms-120ms(取决于硬件)。

Variable component depends on surviving of objects in young space (thus it changes from collection to collection). 可变组件取决于年轻空间中对象的存活(因此它从集合变为集合)。 It is really application specific, but you usually can reduce it by reducing young space (at cost of more frequent pauses). 它确实是应用程序特定的,但您通常可以通过减少年轻空间来减少它(以更频繁的暂停为代价)。

In your case for 4 GiB of young space you have 500ms. 在你的情况下,4 GiB的年轻空间,你有500毫秒。 Assuming variable component is 400ms,if you reduce young space to 1 GiB you should have ~200ms pauses (but 2 times per second). 假设变量分量为400ms,如果将年轻空间减少到1 GiB,则应该有〜200ms的暂停(但每秒2次)。

Another approach is to use more CPU cores, young GC paralleling extremely well . 另一种方法是使用更多的CPU核心,年轻的GC并行非常好

G1 and Shenandoah (experimental) garbage collectors provide great elasticity and unlock vertical scaling for Java applications optimizing memory usage according to the current load. G1和Shenandoah(实验性)垃圾收集器为Java应用程序提供了极大的弹性和解锁垂直扩展,根据当前负载优化了内存使用。 More specifics how it works are at the article Minimize Java Memory Usage with the Right Garbage Collector 更多细节如何工作是在文章最小化Java内存使用与正确的垃圾收集器

容器中的Java弹性

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM