views:

730

answers:

6

I've read plenty of articles about tuning GC in Java and have often wondered how many people really use some of the more advanced features.

I've always avoided tuning where possible and concentrated on writing the simplest possible code I can (Brian Goetz's advice) - this seems to have worked well for me so far.

Are these tuning strategies resilient to change across VM versions or do they require constant re-assessment?

The one tuning that I have made use of is the -server flag.

+6  A: 

I have to say that I haven't had the need myself to use tuning very much. But I work closely with people who write code where latency is critical: they make much use of such tuning - specifying which GC algorithm to use, max pause times, survivor ratios etc.

I guess the answer therefore is: if latency is critical to an application, you might need to look at tuning your GC

oxbow_lakes
+16  A: 

Part of my current job is the care and feeding of a large java application that was designed to run with a large amount of memory (currently around 8 Gb), mostly due to ongoing calculations with lots of cached data. I did the initial deployment with the standard GC setup , mostly because there wasn't a simple way to simulate the production environment running at full tilt.

In stages, over the next few months, I've customized the GC settings. Generally, the biggest available knob seems to be adjusting the frequency and magnitude of incremental gc - the biggest improvement has been in trading off large periodic gc for smaller and more frequent ones. But we've definitely been able to see performance improvements.

I'm not going to post my specific settings because a) they're specific to our setup, and b) because I don't have them handy :). But in general, what I've found is

  • there's been a lot of work done in tuning the default gc settings. Almost always the defaults work better than any tweaks I would make.
  • At least for me, the situations where gc tuning was actually worthwhile were extreme enough that it was unreasonable to attempt to simulate them, so I had to do it experimentally and incrementally.

Here's a good reference from a prev. stackoverflow discussion.

Steve B.
+6  A: 

The vast majority of developers will never have to (or want to) tune GC. I have worked with people who have had to tune it and here is the advice:

Before you attempt to tune the garbage collector make 100% sure you have verified, with a profiler. what is going on. Once you start tuning make sure you verify, with a profiler, that it had a positive effect.

You should also revisit the changes with each version of the VM you run on (different VMs will have different tuning strategies).

I once helped someone with an GC issue that turned out to be them not closing JDBC result sets (or some issue like that). This caused memory to never be freed (his code held onto them for some reason). Fixing that issue made the program go from 20 minutes to something like 30 seconds or a couple of minutes. The memory usage went way down as well.

TofuBeer
Thats what I am concerned about. Any tuning strategies will need to be checked whenever a JVM release takes place and even at regular intervals throughout the dev cycle - thats why I avoid tuning.
Fortyrunner
The VM is volatile, they make changes/improvements to GC with each release, so even "urban legends" about performance improvements are likely wrong by the time you hear them... always write you code clean and i'll likely be fast enough, if not it'll be easier to speed it up.
TofuBeer
+2  A: 

I would say the most common thing to tune is the maximum memory size. Most of the other memory options have sensible defaults and are often over tuned IMHO. i.e. Set when it really doesn't make much difference. I often see people set lots of options when half of them are the default in any case. ;)

Using a profiler is the most useful way to improve GC behaviour (by reducing the number of objects created)

Peter Lawrey
I'm not sure that most people would see setting the Xmx parameter as "tuning" GC.
oxbow_lakes
I disagree a little. If you have a busy box and allocate too much memory - this can cause the box to swap memory too much.
Fortyrunner
Good points, using -mx may not be considered GC tuning, but it often the only thing you need to get right. As @Fortyrunner points out you don't want it to be too large, or too small. I have found you don't want the JVM to use more than one memory bank if you can help it.
Peter Lawrey
+3  A: 

I have but not recently. The application that I was working on was real-time rendering of a video stream constructed of individual motion JPEG images. At the time (circa JDK 1.2 and 1.3), the -Xincgc setting would switch the client garbage collector from more of a big bang cleanup to a mode where a bit of garbage was cleaned up regularly. As a result, the distribution of frame latencies was much lower, giving the impression of a smoother video (instead of 1-2-3-pause, 1-2-3-pause).

I haven't looked at that code in quite a long time but I strongly suspect that, with the modern garbage collection algorithms, -Xincgc would actually decrease performance.

In today's world, I would say that standard optimization skepticism should always apply: profile profile profile. Are you sure that the bottleneck is really the garbage collector...?

Bob Cross
It probably does decrease overall performance but it could still improve latency a lot. C++ shared_ptr reference counting for example, can be slower than Java GC but the overall effect is *so much smoother*.
Zan Lynx
@Zan, I don't think I understand your comment. What I was saying was that -Xincgc is now too naive. The modern GC has more useful options. I wouldn't even conclude that -Xincgc would lead to smoother latencies without testing.
Bob Cross
@Bob: The point of my comment was that doing continuous small cleanups may make the application take longer to run, but it will be more pleasant to use (if the application is user interactive).
Zan Lynx
@Zan, yes, that's definitely true. That said, I think that with the modern GC algorithms, you'll find smoother performance that runs *faster* than the old -Xincgc.
Bob Cross
+2  A: 

In short, yes, it's very useful for tuning any serious Java application. We've often found that in production scenarios it's the difference between a stable app and a completely unpredictable app. It's certainly not the first thing I do but once you have an application working and can apply real load to it, it's one of the first things to investigate at that point.

Alex Miller