Scale up a real-time Java application

With GC tuning, I can successfully get real-time performance for Java applications and avoid recognizable GC pauses. But this holds up to ~ 20 GB of heap space.

Reducing the cost of hardware ensured the availability of even 100 GB of RAM. But, still with Java due to GC pauses, higher heap sizes such as 50 GB can send you into a nightmare in normal times.

I understand that there are options like heap and distributed heap. But the heap has a drawback: se / derialization and a distributed heap on the hand increases the cost of maintenance. In addition, in a distributed heap, you actually do not fully utilize RAM (say, 64 GB), which these days are becoming commonplace as a commodity.

Therefore, to take full advantage of the potential of RAM, what are good solutions for scaling Java applications?

+7
java garbage-collection jvm heap-memory
source share
4 answers

I am working on a primitive collection library called Banana . Banana addresses those exact issues. It quickly supports LinkedLists, HashMaps, and possibly other data structures without the overhead of storing N objects. basically - the entire storage can be inside the int [] (or many) array.

While I have not yet officially published it, most of them have been well tested, and I have already successfully launched it on servers with 144 GB of RAM, maintaining fast and stable performance without any GC pauses.

Give up on this hash map test to get an idea of ​​how to use Banana to store data and how it scales vertically.

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

See the wiki for more details.

+5
source share

Garbage collection time is a function of the number of living objects in your heap. This means that if your distribution level is very high, but the number of live objects is always low, you can use as much RAM as you want, without significant pauses.

This statement is especially true for Troughput collectors ( -XX:+UseParallelOldGC ).

If you are using CMS, you probably want to check its incremental mode ( -XX:+CMSIncrementalMode ). It will run smaller CMS cycles to clear a smaller portion of your heap while using your equipment and without STW pauses.

If CMS is not an option, you should take a look at G1 ( -XX:+UseG1GC ), which is a new garbage collector designed for large heaps. Principle: clean only a few heap areas in each cycle, but make sure that these regions contain a lot of dead objects (quick profit).

Hope this helps!

Sources:

0
source share

I did some research on JVM heap size scaling. You can read more here and here .

The main conclusion: the young GC-pause has two components of constant and variable.

The constant component depends on the size of the old space and for 64GiB, I expect it to be 80 ms-120 ms (depending on the hardware).

The variable component depends on the survival of objects in a young space (thus, it changes from collection to collection). This is really application-specific, but you can usually reduce it by reducing the young space (due to more frequent pauses).

In your case, for 4 GiB of youthful space, you have 500 ms. Assuming a variable component of 400 ms, if you reduce the young space to 1 GB, you should have ~ 200 ms pauses (but 2 times per second).

Another approach is to use more processor cores, the young GC parallel is very good .

0
source share

G1 and Shenandoah (experimental) garbage collectors provide greater elasticity and unlock vertical scaling for Java applications, optimizing memory usage to suit the current load. For more information on how this works, see Minimize Java memory usage with the correct garbage collector.

Java Elastic in Containers

0
source share

All Articles