Why does the java8 GC not collect for over 11 hour

2019-01-27 06:54发布

问题:

Context: 64 bit Oracle Java SE 1.8.0_20-b26

For over 11 hours, my running java8 app has been accumulating objects in the Tenured generation (close to 25%). So, I manually clicked on the Perform GC button in jconsole and you can see the precipitous drop in heap memory on the right of the chart. I don't have any special VM options turned on except for XX:NewRatio=2.

Why does the GC not clean up the tenured generation ?

回答1:

This is a fully expected and desirable behavior. The JVM has been successfully avoiding a Major GC by performing timely Minor GC's all along. A Minor GC, by definition, does not touch the Tenured Generation, and the key idea behind generational garbage collectors is that precisely this pattern will emerge.

You should be very satisfied with how your application is humming along.



回答2:

The throughput collector's primary goal is, as its name says, throughput (via GCTimeRatio). Its secondary goal is pause times (MaxGCPauseMillis). Only as tertiary goal it considers keeping the memory footprint low.

If you want to achieve a low heap size you will have to relax the other two goals.

You may also want to lower MaxHeapFreeRatio to allow the JVM to yield back memory to the OS.



回答3:

Why does the GC not clean up the tenured generation ?

Because it doesn't need to.

It looks like your application is accumulating tenured garbage at a relatively slow rate, and there was still plenty of space for tenured objects. The "throughput" collector generally only runs when a space fills up. That is the most efficient in terms of CPU usage ... which is what the throughput collector optimizes for.

In short, the GC is working as intended.

If you are concerned by the amount of memory that is being used (because the tenured space is not being collected), you could try running the application with a smaller heap. However, the graph indicates that the application's initial behavior may be significantly different to its steady-state behavior. In other words, your application may require a large heap to start with. If that is the case, then reducing the heap size could stop the application working, or at least make the startup phase a lot slower.