Garbage collection from Java garbage affecting performance

I notice a strange phenomenon in my application. I store objects in the Hashmap after sending them to the server and delete them when the answer comes.

I recently noticed a very slow performance after launch. After checking, I found that the memory usage is 4 GB and then drops to less than 1 GB. I suspect it cleans up a lot of objects, so performance is so poor.

So the question is, why does it take Java to collect garbage so late? That is, why wait until the heap is full, and then do the garbage collection? Do not collect garbage at regular intervals.

Objects that are stored in the HashMap are created right at this very time, that is, they are not durable.

This is on Linux (RHEL), Oracle JVM HotSpot 7. 64-bit. 4 cores. Here's how the application starts:

java -jar -Xmx4g prog.jar

Note: I saw this: Configuring garbage collectors for low latency But for now I want to understand why the GC has been taking so long?

+6
source share
3 answers

It looks like you have one of two problems:

  • If you have objects with a long residence, they will be moved from the younger generation to something older (for example, on HotSpot in the Mark-Compact Generation .) That is, they will no longer refer to the count for collection and will be saved for a slower GC.
  • Your heap space for the younger generation is too small for your use pattern forcing objects to move from younger to older generation.

I would see how to tune the younger generation for more. See the Generation Garbage Collection and look at the different types of generations.

+3
source

So the question is, why does it take Java to collect garbage so late? That is, why wait until the heap is full, and then do the garbage collection? Do not collect garbage at regular intervals.

You use the Bandwidth garbage collector, and that is how the collector collects it. It aims to maximize system throughput by minimizing the percentage of CPU time spent on garbage collection. He does this with a simple wait strategy until the heap (or rather, a new space of objects) is full. Other things being equal, the most effective:

  • collect garbage when you have a lot of it, and
  • stop everything else while you collect garbage.

(To understand why you need to understand the technical details of how copy collectors work ...)

Of course, this means that you get significant pauses.

If you need low latency, you need to use another collector. However, this leads to a larger percentage of the actual processor time spent collecting garbage ... and other overhead associated with the GC.


If you get a lot of significant pauses, then there may also be a problem with the relative size of the spaces. But before you start playing with the related parameters, you will be asked to turn on the GC log to try to understand what causes the pauses and how frequent they are.

+1
source

This is simply because the GC does not start by default if the heap is full.

The default garbage collector selected by the JVM is Parallel GC. Its purpose is to free as much memory as possible during the shortest possible pause. He will not begin in his youth, unless Eden is full. Similarly, it will not run in the old generation unless Tenured is full.

You can switch to CMS if you want to regularly clear the memory. Just use the -XX:+UseConcMarkSweepGC . However, this will mean some overhead for your application. This is the cost of having a GC that runs at regular intervals without pausing your application.

So to summarize:

  • Parallel GC pauses the application, runs only when there is no other choice.

  • CMS starts at the same time without pausing your application, has some utility

Source: http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html

0
source

Source: https://habr.com/ru/post/944835/


All Articles