JDK-6505535 : jmap -histo options print negative number for large set of objects
  • Type: Bug
  • Component: core-svc
  • Sub-Component: tools
  • Affected Version: 6,7,7u79
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: generic,linux
  • CPU: generic,x86
  • Submitted: 2006-12-18
  • Updated: 2014-12-17
  • Resolved: 2011-03-08
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7
6u4Fixed 7 b12Fixed
Related Reports
Duplicate :  
Relates :  
Description
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 ----------

Comments
SUGGESTED FIX ------- heapInspection.cpp ------- 55,57c55,58 < st->print_cr("%9d %9d %s", < _instance_count, < _instance_words * HeapWordSize, --- > // simplify the formatting (ILP32 vs LP64) - always cast the numbers to 64-bit > st->print_cr("%13" FORMAT64_MODIFIER "d %13" FORMAT64_MODIFIER "u %s", > (jlong) _instance_count, > (julong) _instance_words * HeapWordSize, 157,158c158,160 < jint total = 0; < size_t totalw = 0; --- > // simplify the formatting (ILP32 vs LP64) - store the sum in 64-bit > jlong total = 0; > julong totalw = 0; 160c162 < st->print("%3d: ", i+1); --- > st->print("%4d: ", i+1); 165c167,168 < st->print_cr("Total %8d %9d", total, totalw * HeapWordSize); --- > st->print_cr("Total %13" FORMAT64_MODIFIER "d %13" FORMAT64_MODIFIER "u", > total, totalw * HeapWordSize); 224,225c227,228 < "num #instances #bytes class name\n" < "--------------------------------------", --- > " num #instances #bytes class name\n" > "----------------------------------------------",
30-03-2007

EVALUATION The output format of the total size was hardcoded for 32-bit integer which fails to deal with large heap memory.
30-03-2007