Wednesday, 22 May 2019

Java Integer Cache


IntegerCache class is introduced in Java to save memory and improve performance.

As you see java source code, IntegerCache class is a private static class nested in Integer class.

public final class Integer extends Number implements Comparable<Integer> {
 ........
 ........
 ........
 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() {
  }
 ........
 ........
 ........
}

First, let's try to understand how IntegerCache works.


App.java
package com.sample.app;

public class App {

 public static void main(String args[]) throws Exception {
  Integer i1 = 123;
  Integer i2 = 123;
    
  Integer i3 = 12345;
  Integer i4 = 12345;
  
  System.out.println("i1 == i2 : " + (i1 == i2));
  System.out.println("i3 == i4 : " + (i3 == i4));
 }
}

Any guess on the output of the program. Ideal guess is such that, since i1 and i2 are two different objects, i1==i2 return false, similarly i3==i4 also return false.

But when you ran App.java, you can see below output.

i1 == i2 : true
i3 == i4 : false

Surprised!!!!!, it is because of IntegerCache. Integer values between the range –128 to +127 (inclusive)  are cached and reused when required.

Integer cache only works on autobixing
If you create an integer via constructor notation, then IntegerCache is nowhere in the picture.


App.java
package com.sample.app;

public class App {

 public static void main(String args[]) throws Exception {
  Integer i1 = new Integer(123);
  Integer i2 = new Integer(123);
    
  Integer i3 = 12345;
  Integer i4 = 12345;
  
  System.out.println("i1 == i2 : " + (i1 == i2));
  System.out.println("i3 == i4 : " + (i3 == i4));
 }
}

Output
i1 == i2 : false
i3 == i4 : false

Similar to IntegerCache, Java also has ByteCache, ShortCache, LongCache, CharacterCache implementations.

Can I control the size of IntegerCache?
Yes, the size of the cache may be controlled by the '-XX:AutoBoxCacheMax=<size>'' option

Can I set the high value that is going to be stored in IntegerCache?
Yes, During VM initialization, java.lang.Integer.IntegerCache.high property may be set and saved in the private system properties in the sun.misc.VM class.

Java read the property 'java.lang.Integer.IntegerCache.high' during jvm initialization.

Example

sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");


You may like



No comments:

Post a Comment