Reputation:
I'm noticing a weird phenomenon in my application. I store Objects in a Hashmap after submitting them to a server and remove them when the response arrives.
I recently noticed very slow performance after running. Upon checking, I discovered that the memory usage stays at 4GB and then drops to less than 1 GB. I suspect that it is cleaning up a lot of objects that's why the performance gets so bad.
So the question is why it is taking for Java to Garbage Collect so late? That is, why wait until the Heap is full and then do Garbage collection? Shouldn't it collect the garbage at regular intervals.
The objects which gets stored in the HashMap gets created right at that very time, that is they are not long lived.
This is on Linux (RHEL), Oracle JVM HotSpot 7. 64-bit. 4 cores. This is how the app is run:
java -jar -Xmx4g prog.jar
Note: I have seen this: Tuning garbage collections for low latency But for now I want to understand why the GC is taking so long to kick in?
Upvotes: 7
Views: 1628
Reputation: 1215
It is simply because the default GC does not start unless the heap is full.
The default garbage collector that is selected by the JVM is the Parallel GC. Its goals are to free as much memory as possible during the shortest possible stop-the-world pause. It won't start in young generation unless Eden is full. Similarly, it won't start in old generation unless Tenured is full.
You can switch to CMS if you want to regularly clean up memory. Simply use the flag -XX:+UseConcMarkSweepGC
. However, it will imply some overhead on your application. This is the cost of having a GC that runs at regular intervals without pausing your application.
So, to sum up :
Parallel GC pauses the application, starts only when there is no other choice
CMS runs concurrently without pausing your application, has some overhead
Source : http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html
Upvotes: 0
Reputation: 719476
So the question is why it is taking for Java to Garbage Collect so late? That is, why wait until the Heap is full and then do Garbage collection? Shouldn't it collect the garbage at regular intervals.
You are using the "Throughput" garbage collector, and that is how that collector is designed to behave. It aims to maximize system throughput by minimizing the percentage of CPU time spent doing garbage collection. It does this by the simple strategy of waiting until the heap (or more precisely, the new object space) is full. All things being equal, it is most efficient to:
(To understand why, you need to understand the technical details of how copying collectors work ...)
Of course, that means you get significant pauses.
If you want low latency, you need to use a different collector. However, this results in a larger percentage of actual CPU time being spent on garbage collection ... and other GC-related overheads.
If you are getting a lot of significant pauses, then there may also be an issue with the relative size of spaces. But before you fiddle with the related parameters, you would be advised to turn on GC logging to try to get a handle on what is causing the pauses and how frequent they are.
Upvotes: 1
Reputation: 35980
It sounds like you have one of two issues going on:
I'd look at tuning your young generation to be larger. See Generational Garbage Collection and look at the various types of generations.
Upvotes: 3