The Internal Cache of Integers

Instances of Integer and other wrapper classes are cached by the JVM for increased performance.

package collections;
 
public class IntegerCache {
	private static void test(Integer i, Integer i2) {
		System.out.println(i);
		if (i == i2)
			System.out.println(" the same");
		if (i != i2)
			System.out.println(" different");
		if (i.equals(i2))
			System.out.println(" equal");
	}
 
	public static void main(String[] args) {
		test(17, 17);
		test(200, 200);
	}
}

Output of above code would be :

17
the same
equal
200
different
equal

The Cache Internals
The cache is used as follows, as seen in the source code of java.lang.Integer.

 public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
 }

The actual cache can be found in java.lang.Integer and looks as follows.

 ... 
   private static class IntegerCache {
     static final int low = -128;
     static final int high;
     static final Integer cache[];
     static { // high value may be configured by property
       int h = 127;
       String integerCacheHighPropValue = 
         sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
       if (integerCacheHighPropValue != null) {
         try {
           int i = parseInt(integerCacheHighPropValue);
           i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE
           h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
         } catch( NumberFormatException nfe) {
           // If the property cannot be parsed into an int, ignore it. 
         } 
       }
       high = h;
       cache = new Integer[(high - low) + 1];
       int j = low;
       for(int k = 0; k < cache.length; k++)
         cache[k] = new Integer(j++);
       // range [-128, 127] must be interned (JLS7 5.1.7)
       assert IntegerCache.high >= 127;
     }
     private IntegerCache() {}
   } ...

Note how the cache is pre-filled on startup rather than on demand, meaning that the memory footprint of the cache is constant no matter which Integers are actually used in the VM. Tweaking the cache to a very large size thus comes with a steep prize in terms of memory consumption.

Interestingly enough, the parameter to set the size of the cache only affects the upper limit and never the lower, meaning that there is no simple way to get Integers smaller than -128 to be interned in the cache.

The size of the cache can be tweaked with the -XX:AutoBoxCacheMax= option

Mar Java Mit Java 🙂

Uday Ogra

Connect with me at http://facebook.com/tendulkarogra and lets have some healthy discussion :)

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *