JDK-6493335 : Mismatch between -Xm[sx] and verbose:gc output
  • Type: Bug
  • Component: hotspot
  • Sub-Component: gc
  • Affected Version: 6
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic
  • CPU: generic
  • Submitted: 2006-11-14
  • Updated: 2013-05-03
  • Resolved: 2013-05-03
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Description
As with 6493287, we're playing with the leaky program

------------------------------------------
import java.util.concurrent.*;

public class Bug3 {
    private static int intArg(String[] args, int i, int defaultValue) {
	return args.length > i ? Integer.parseInt(args[i]) : defaultValue;
    }

    public static void main(String[] args) {
	final BlockingQueue<Object> q = new LinkedBlockingQueue<Object>();
	final int threads = intArg(args, 0, 10);
	final int millis  = intArg(args, 1, 100);

	for (int i = 0; i < threads; i++)
            new Thread() { public void run() {
		while (true) {
		    try { q.poll(millis, TimeUnit.MILLISECONDS); }
		    catch (Throwable t) { throw new Error(t); }}}}.start();
    }
}
------------------------------------------

When specifying command line flags
-Xms3m -Xmx3m
I expect that the total heap size reported by -verbose:gc
(that is, the number in parentheses)
- will be about 3m
- will be constant.

Instead, I find that the reported total heap size sometimes grows, and
is often much larger than 3m (6m-8m).

Here's a run on linux-i586:

 $ jver 6 jr -verbose:gc -Xmx3m -Xms3m -XX:+UseSerialGC -server  Bug3 10 100
==> javac -source 1.6 -Xlint:all Bug3.java
==> java -verbose:gc -Xmx3m -Xms3m -XX:+UseSerialGC -server -esa -ea Bug3 10 100
[GC 896K->626K(3008K), 0.0155790 secs]
[GC 1522K->1481K(3008K), 0.0197380 secs]
[GC 2377K->2363K(3264K), 0.0158610 secs]
[Full GC 2363K->2363K(3264K), 0.0720340 secs]
[GC 3200K->3173K(4800K), 0.0368410 secs]
[GC 4069K->4064K(5056K), 0.0149100 secs]
[Full GC 4064K->4064K(5056K), 0.1115110 secs]
[GC 4960K->4939K(6080K), 0.0142320 secs]
[Full GC 5835K->5816K(6080K), 0.1493120 secs]
[Full GC 6016K->5996K(6080K), 0.1833290 secs]
[Full GC 6079K->6077K(6080K), 0.1464510 secs]
[Full GC 6079K->6077K(6080K), 0.1460160 secs]

Here's a run on solaris-sparc:

 $ jver 6 jr -verbose:gc -Xmx3m -Xms3m -XX:+UseParallelGC -client Bug3 10 100
==> javac -source 1.6 -Xlint:all Bug3.java
==> java -verbose:gc -Xmx3m -Xms3m -XX:+UseParallelGC -client -esa -ea Bug3 10 100
[GC 1664K->1396K(6016K), 0.0308614 secs]
[GC 3060K->3000K(6016K), 0.0459820 secs]
[Full GC 3000K->2999K(7936K), 0.0641902 secs]
[GC 4663K->4551K(7936K), 0.0819884 secs]
[GC 6215K->6143K(7936K), 0.0414826 secs]
[Full GC 6143K->6143K(7936K), 0.1156834 secs]
[Full GC 7679K->7677K(7936K), 0.1436284 secs]
[Full GC 7679K->7527K(7936K), 0.1652214 secs]

Comments
Going with Thomas' suggestion and closing this bug as a duplicate of JDK-8006088.
03-05-2013

Note that this behavior, changing maxheapsize according to NewSize + Oldsize even if maxheapsize has been set on the command line, observed by John Coomes, has been fixed in 8006088. Maybe set this as duplicate if with the patch for 8006088 the observed behavior is fixed.
21-03-2013

WORK AROUND A partial workaround is to use the command line options: -Xms3m -Xmx3m -XX:NewSize=1m -XX:OldSize=2m Then the max heap size will be rounded to 4m instead of 8m.
30-06-2007

EVALUATION The default value for OldSize (initial size of the old generation) is 4m and the default NewSize (initial size of the young generation) is 2176K on sparc, which obviously add up to more than -Xmx value of 3m. The heap initialization code notices this and sets the max heap size to the sum of OldSize + NewSize, which is 6272K. Then the problem described in bug 4885313 kicks in: the max heap size is rounded up to a multiple of 512 * page_size == 512 * 8K == 4M, so the max heap size becomes 8M. The heap grows because the initial heap size is not increased the same way as the max heap size.
30-06-2007