3

How to increase the rate of GC calls in java? Are there any JVM parameters to tune the rate at which GC gets called?

Thanks!!

cooltechnomax
  • 681
  • 3
  • 10
  • 21
  • 2
    Why would you want to increase the rate of GCs? What are you **really** trying to optimize? And yes: there are [plenty of ways to tweak the GC](http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html). – Joachim Sauer Aug 02 '11 at 16:55
  • 2
    Don't call System.gc(). Please. http://stackoverflow.com/questions/2414105/why-is-it-a-bad-practice-to-call-system-gc – Jim Aug 02 '11 at 16:55
  • Check out similar posts in the **Related** column on the right... specifically this: [Does anyone know of a good guide to configure GC in Java?](http://stackoverflow.com/questions/4505987/does-anyone-know-of-a-good-guide-to-configure-gc-in-java) – Péter Török Aug 02 '11 at 16:56
  • 1
    Increasing the rate of GC calls will not solve your problem if GC is taking up a significant chunk of CPU usage; it will only worsen things. If your JVM is well tuned, then it should invoke GC only occassionally to clean up the young gen, and the old gen on lesser occasions. – Vineet Reynolds Aug 02 '11 at 17:00

1 Answers1

5

If you change the GC pause time, garbage collection should take place more frequently. This may be useful for some time critical apps where you need garbage collections to not take as long as it might, even if there may be more collections. -XpauseTarget should do this as a VM argument. Minimum value here is 10 milliseconds. Don't call System.gc(). Depending on where you call it, you could make your application hugely inefficient.

The best idea is to simply optimise your application to use fewer objects. You can use a tool such as JVisualVM which comes with the JDK to inspect your app at runtime and find out where the problem lies, and also to look at the garbage collection info.

You could also try a different garbage collector. I use the following, and it helps me in some applications where memory usage, say, is more important than CPU time (although there's a few useless options here -- just weed them out):

-Xincgc
-XX:+CMSIncrementalPacing
-XX:+UseAdaptiveSizePolicy
-XX:+AggressiveOpts
-XX:+ExplicitGCInvokesConcurrent
-XX:+UnlockExperimentalVMOptions
-XX:+UseConcMarkSweepGC
-XX:UseSSE=3
-XX:+UseParNewGC
-XX:SurvivorRatio=2
-XX:NewRatio=8
-XX:+DoEscapeAnalysis
-XX:+UseFastAccessorMethods
-XX:+ForceTimeHighResolution
-XX:+UseTLAB
-XX:+ResizeTLAB
-XX:MaxGCPauseMillis=10
-XX:ParallelGCThreads=8
-XX:+CMSParallelRemarkEnabled
-XX:+DisableExplicitGC
-XX:+UseAdaptiveGCBoundary
-XX:-UseGCOverheadLimit
-Xnoclassgc
-server
-Xss128k
-Xms1g
-Xmx1g
Chris Dennett
  • 22,412
  • 8
  • 58
  • 84
  • +1 Was about to write up something similar, but it is mostly covered here. Just a note to add, the garbage first (g1) garbage collector is very different than the current default garbage collector. Switching to it means unlearning a lot of the currently held assumptions, and it's going to be default in Java 7 (unless they change their minds again). – Edwin Buck Aug 02 '11 at 17:27
  • You might find this article about collectors interesting too: http://useless-factor.blogspot.com/2008/03/some-more-advanced-gc-techniques.html :) – Chris Dennett Aug 02 '11 at 18:35
  • Thanks a lot for your reply. My application uses native opengl calls. When I track the memory usage in JVisualVM, it doesn't show any inconsistency. However, when process memory is tracked in Windows Task Manager it shows a steady increase. If I call System.gc() explicitly, then the process memory also show a sawtooth pattern. I want to avoid the System.gc() calls so tried MaxGCPauseMillis VM parameter and it works fine. But I am not sure if this is the right way to solve the issue. – cooltechnomax Aug 02 '11 at 19:25
  • @cooltechnomax, if it's using jni to bind with OpenGL (and i can't imagine how it wouldn't) then your program may be leaking memory on the non-managed memory side of things. Java's garbage collector is only responsible for memory the JVM creates, not memory allocated in the jni layer. If you are leaking in your C / C++ calls then it would explain why the process is growing in memory, but the JVM doesn't know about it (since it wasn't involved directly in the memory's allocation). – Edwin Buck Aug 02 '11 at 19:54
  • @Edwin Buck: I tried debugging the native calls as well but couldn't find any leak. If there is a leak in jni layer, I cannot understand why System.gc() keeps the memory in check. Shouldn't the memory keep on increasing irrespective of System.gc() calls? – cooltechnomax Aug 02 '11 at 20:05
  • You wouldn't have left your VisualVM connector alive by any chance? It might be caching data that System.gc() reaps. In other words, it might not actually be your app, but the collecting of data to report to VisualVM that describes the discrepancies. And yes, if it were a jni layer issue, then System.gc() would do nothing (as you correctly deduced). – Edwin Buck Aug 02 '11 at 20:40
  • System.gc() can clean up native-allocated buffers that don't get disposed. Check in JVisualVM :) – Chris Dennett Aug 02 '11 at 22:15