FULL PRODUCT VERSION :
java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) 64-Bit Server VM (build 1.6.0-b105, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux 2.6.9-22.20.ELsmp #1 SMP Fri Nov 18 03:04:44 EST 2005 x86_64 x86_64 x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
When we try to use jmap -histo to display the heap information, we find that sometimes it will print negative number due to integer overflow. This manifest itself fairly often as our application tends to use large heap size on 64bit platform.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1) Build a jvm instance with instance of a class that is more then 2G in size - you can use program I have attached
2) run this on a 64-bit JVM, with java -Xmx4G LargeObjectArrayList
3) Once the Array list allocation has finished, it prints "Press return to stop". You should then use jmap -histo to obtain a histogram of the heap
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The total number of bytes used by all the instance of the class, with size > 0
ACTUAL -
When you run jmap -histo for the test case, you will see the following:
num #instances #bytes class name
--------------------------------------
1: 330 -1431629248 [Ljava.lang.Object;
2: 10000 640000 LargeObjectSize$LargeObject
3: 4588 555040 <methodKlass>
4: 4588 526456 <constMethodKlass>
5: 304 334336 <constantPoolKlass>
6: 6852 304904 <symbolKlass>
7: 283 235264 <constantPoolCacheKlass>
8: 304 212672 <instanceKlassKlass>
9: 345 146984 [I
10: 1032 121712 [C
11: 494 99104 [B
<output removed to save space>
190: 1 16 java.lang.String$CaseInsensitiveComparator
191: 1 16 java.lang.reflect.ReflectAccess
Total 32419 -1428175088
Notice that the array of objects at the top printed with negative number, as well as the total.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.ArrayList;
public class LargeObjectArrayList {
public class LargeObject {
long a,b,c,d,e;
}
private ArrayList<LargeObject> justStore = new ArrayList<LargeObject>(10000);
public LargeObjectSize() {
for(int i=0; i<10000; i++) {
justStore.add(new LargeObject());
}
}
public static void main(String[] args) throws Exception {
LargeObjectArrayList los = new LargeObjectArrayList();
System.out.println("Press return to stop");
System.in.read();
}
}
---------- END SOURCE ----------