I\'m having a hard time dealing with a Java garbage collection problem, and interpreting the logs.
My application requires that no GC takes longer than 2 seconds, and id
Turns out the problem was that the heap was getting swapped out to disk, and the delay was Java's GC having to wait for it to be swapped back in.
Solved (mostly) by setting Linux' "swappiness" parameter to 0.
In general, it's tough to get GC tuning right when you require such a large heap.
That being said, most of GC hang time is caused by the memory copying of objects that survive across young garbage collections.
Is your ConcurrentLinkedHashMap initialized with all the memory-persistent objects all at once? Or does it slowly grow bigger as the application keeps running? If it's the latter, it may be difficult to cut down your GC hang times since there are objects that always survive. If it's the former, you will need to size your tenured generation with the size of your persistent objects + 20% or so, and make sure that your young gen is large enough to keep up with the transient objects that are created during the course of your application.
Perhaps the performance limit of 200ms is too strict and you need to manage garbage collection on your own? have you tried this with a larger limit?
Can you post/link to the code of the ConcurrentLinkedHashMap implementation? If this is the implementation I've posted, please open a ticket on the project page so we can debug it together. If not, knowing the details of your implementation would help to determine where the issue might lie.
have you seen this?
http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html
also, take a look at...
http://java.sun.com/javase/6/docs/technotes/guides/visualvm/index.html
I think your attention might be a little misdirected.
Spend a little time in a profiler finding your biggest allocation hotspots. If there are just a few places in your code where the majority of your allocations occur, try using an object pool rather than always constructing new objects.
Collection classes and StringBuilders are great candidates for pooling. When you return them to the pool, call the collection.clear() or the stringbuilder.setLength(0) methods, so that they're ready for consumption when the next caller wants to retrieve them from the pool.
The best way to tune the GC is by creating fewer objects. There are lots of strategies for eliminating allocations, and pooling is just one of them (though one of my favorites).
UPDATE: It's been five years since I wrote this answer, and my opinion on pooling has mostly changed. Back when I wrote this answer in 2009, I could frequently use object pooling (even of simple objects like StringBuilder) to speed up tight inner loops with lots of allocations. These days, it's harder to find cases where pooling doesn't make the situation worse. I almost never use pools for anything other than threads or connections. Still though, it's a nice tool to have at your disposal, even if you don't use it often.