Jon Masamitsu's Weblog

  • Java
    January 10, 2008

GC Errata 2

Guest Author
I know that none of you are still making the transition from
jdk1.4.2 to jdk5 (aka jdk1.5.0, yah, we changed the numbering)
but if you were, I'd want you to know that you might need
a larger permanent generation. In jdk5 class data sharing was
implemented (the -Xshare option, see the "java -X" output)
when the client VM (-client) is being used.
The implementation of class data sharing split some of the
information about classes into two parts (the part that
can be shared and the part that is specific to an execution
of the JVM). The space in the
permanent generation for classes that can be shared
increased by 10-20%. That doesn't mean that you need
a permanent generation that is 10-20% larger! Only
some of the classes are affected and only some of the
data structures for those classes are affected. But if
you're running a tight ship in terms of the size of
permanent generation, you might be affected by this. Of course,
none of you are still making the transition to jdk5.

Some users have reported occasional long pauses which occur at the
time of a GC but cannot be accounted for by GC times.
Such long pauses may be a symptom of a known latency in the use of (Linux's) mprotect()
which is used by the JVM while steering application threads to so-called
safepoints. A known workaround at the JVM level to step around the
Linux mprotect() issue is the use of JVM option -XX:+UseMembar.

The real fix, unfortunately, lies in the Linux kernel; see
http://bugzilla.kernel.org/show_bug.cgi?id=5493. You might wish to
pursue this with your Linux support engineer and see if a patch
is available for the problem.

To avoid running into this bug, make sure there is plenty of physical memory
free in your system so that the Linux pager does not start evicting pages
for any process from memory to swap.

If you're seeing large variations in your minor GC pauses and are using
UseParNewGC (which is on by default with the low pause collector),
you might be running into 6433335. A large variation is a factor of a 100.
This is a bug that has to do with large objects (or large free blocks) in the
heap. If you turn off UseParNewGC and see larger pauses (by a multiplier that is
on the order of the number of cpu's) but more regular pauses, then 6433335 is
a likely candidate. It's been fixed in jdk 1.4.2 update 14, jdk 5 update 10
and jdk 6 update 1.

I've heard of more than one report recently of crashes with the low-pause
collector that were caused by bug

6558100 - CMS crash following parallel work queue overflow

This bug is fixed in 1.4.2u18, 5.0u14 and 6u4. You can workaround the
bug with the flag -XX:-ParallelRemarkEnabled. You could also run into
this bug if you explicitly enable ParallelRefProcEnabled, so if you
include -XX:+ParallelRefProcEnabled, remove it.
ParallelRefProcEnabled is off by default so if you don't explicitly
turn it on, don't worry about it.

Starting in jdk6 the biased locking optimization is "on" by default
(command line option UseBiasedLocking). This optimization reduces the cost of
uncontended locks by treating the thread that owns the lock preferentially.
It's a nice optimization but could increase the memory usage of the JVM.

If you move from jdk5 to jdk6 and start seeing messages such as

java.lang.OutOfMemoryError: requested bytes for GrET in C

you could try turning off biased locking and see if it helps. Improvements in
biased locking were made in 6u1 to make this much less of a problem.

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha