default GC/ empty survivor space
I have a web application running on Solaris 8 using JDK 1.5.0_11 on a 64-bit OS. I am uncertain as to what GC algorithm I am using by default; my machine is a server-class machine, as defined by Sun, with 4 processors and 4G of RAM. I have read things that say that the concurrent mark sweep collector is used by default on this machine, as well as others that say that this option MUST be specified to be used. Which is it?
On this same machine, I have observed that if I specify these parameters
-server
-d64
-Xms2304m
-Xmx2304m
-verbose:gc
-Xloggc:<path to file>
-XX:+HeapDumpOnOutOfMemoryError
-XX:+CMSClassUnloadingEnabled
-XX:+CMSPermGenSweepingEnabled
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
according to Jconsole, the "old" generation is empty (never filled). If I indeed *do* specify -XX:+UseConcMarkSweep, Jconsole shows the survivor space as never being filled. This would suggest that unless I specify -XX:+UseConcMarkSweepGC, the concurrent collector won't be used. Is that correct?
Why is it that either the old generation or the survivor space is never filled? What does that indicate? Is/are there other parameters that I should be setting?
Thanks!
[1271 byte] By [
gmhollera] at [2007-11-27 6:04:25]

# 1
Hi,
CMS is never selected as the default collector. You have to explicitly specify -XX:+UseConcMarkSweepGC to use it.
The default collector for server class machines is the parallel collector:
The following changes take effect with J2SE 5.0.
1. On server-class machines running the server VM, the garbage collector (GC) has changed from the previous serial collector (-XX:+UseSerialGC) to a parallel collector (-XX:+UseParallelGC). You can override this default by using the -XX:+UseSerialGC command-line option to the java command.
[http://java.sun.com/j2se/1.5.0/docs/guide/vm/gc-ergonomics.html]
Not seing your old generation being filled is quite unusual. Are you sure you are running your application long enough? All your objects are always allocated in eden. At each young garbage collection cycle, the surviving objects are copied between the survivor spaces. If they have been copied MaxTenuringThreshold times (can be specified explicitly, the default is somehow object to ergonomics), they tenure into the old generation. If you just run your application for a short time, you might never see this happen.
With CMS, the survivor spaces should be used at each young gc cycle for the objects surviving the gc, unless you specify -XX:MaxTenuringThreshold=0.
Also see http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html for more details.
Nick.
# 2
The page you specify is one place that I saw mention of the parallel collector being the default. But I have seen other places where people specify that starting with JDK 1.5.0, the CMS collector is the default for server class machines. But that's not what I see - I have to specify it. So I suspect there's something else going on for them concude that it is now the default.
My application has been running for about 24 hours - 7 full GCs, and an output in Jconsole that looks a lot like what I was expecting - but still an empty survivor space. What I'm wondering currently is that if I explicitly specify some things like the MaxTenuringThreshold instead of letting it default, would that make a difference? Perhaps the behavior some of the options depend on others without meaning to - or pehaps the options I'm using are causing unintended effects?
# 3
In http://forum.java.sun.com/thread.jspa?threadID=5153212&messageID=9579159 I've posted some code to dump some performance data of the JVM. It also contains the entries sun.gc.collector.0.name and sun.gc.collector.1.name which contain the names of the garbage collector for the young (0) and old (1) generation. You can try this to verify that CMS is *not* chosen as default. And I am pretty sure it never was the default on any type of machine because it is rather a special purpose collector -- most server class applications rather require throughput, not response times, and therefore would not want to use CMS.
> but still an empty
> survivor space.
I usually don't use jconsole, but if it really reports empty survivor spaces all the time, this rather sounds like a bug to me. Have you tried "jstat -gc <pid> <interval>"? It will give you the occupancy of the two survivor spaces in the columns "S0U" and "S1U".
Nick.
# 4
I don't doubt you, and it seems that way to me, and there's no harm in just specifying the option, so I guess no harm, no foul. But it makes me wonder where the people that told me CMS was the default for server class machines on JDK1.5.0 got that idea.
Now, I tried that jstat command - "jstat -gc 14367 5s" in my case - and the response was "14367 not found". What does that indicate? I'm on JDK 1.5.0_11 - do I need to be on a later version?
BTW, I added some more options I'd been looking at and restarted my application, and now the generations appear to be garbage collected properly. Here's what I added:
-XX:NewSize=1152m
-XX:MaxNewSize=1152m
-XX:TargetSurvivorRatio=90
-XX:SurvivorRatio=5
-XX:MaxTenuringThreshold=12
I haven't seen a full GC yet, but it's only been a few hours.
Thanks for your help!
# 5
The "14367 not found" can appear if 14367 is not the main thread of your JVM. On Solaris, all threads of the JVM have the same PID. On Linux however, each thread has its PID. I don't know about Windows... If you do a "ps -efa | grep java" on Linux, you will get one entry per thread. You have to find the main thread (the one that created the other ones, see PPID, usually the one with the lowest number). Pass this thread's PID to the command, then it should work.
Nick.