您的位置:首页 > 编程语言 > Java开发

Java Integer 缓存问题

2014-11-20 17:15 246 查看
[html] view
plaincopy

public class Hello   

{   

  public static void main(String[] args)   

  {   

    int a = 1000, b = 1000;   

    System.out.println(a == b);   

  

    Integer c = 1000, d = 1000;   

    System.out.println(c == d);   

  

    Integer e = 100, f = 100;   

    System.out.println(e == f);   

  }   

}   

输出是true,fasle,true。

The Java Language Specification, 3rd Edition 写道:

[html] view
plaincopy

为了节省内存,对于下列包装对象的两个实例,当它们的基本值相同时,他们总是==:  

 Boolean  

 Byte  

 Character, \u0000 - \u007f(7f是十进制的127)  

 Integer, -128 — 127  

jdk源码:

[html] view
plaincopy

/**  

     * Cache to support the object identity semantics of autoboxing for values between   

     * -128 and 127 (inclusive) as required by JLS.  

     *  

     * The cache is initialized on first usage. During VM initialization the  

     * getAndRemoveCacheProperties method may be used to get and remove any system  

     * properites that configure the cache size. At this time, the size of the  

     * cache may be controlled by the vm option -XX:AutoBoxCacheMax=<size>.  

     */  

  

    // value of java.lang.Integer.IntegerCache.high property (obtained during VM init)  

    private static String integerCacheHighPropValue;  

  

    static void getAndRemoveCacheProperties() {  

        if (!sun.misc.VM.isBooted()) {  

            Properties props = System.getProperties();  

            integerCacheHighPropValue =  

                (String)props.remove("java.lang.Integer.IntegerCache.high");  

            if (integerCacheHighPropValue != null)  

                System.setProperties(props);  // remove from system props  

        }  

    }  

  

    private static class IntegerCache {  

        static final int high;  

        static final Integer cache[];  

  

        static {  

            final int low = -128;  

  

            // high value may be configured by property  

            int h = 127;  

            if (integerCacheHighPropValue != null) {  

                // Use Long.decode here to avoid invoking methods that  

                // require Integer's autoboxing cache to be initialized  

                int i = Long.decode(integerCacheHighPropValue).intValue();  

                i = Math.max(i, 127);  

                // Maximum array size is Integer.MAX_VALUE  

                h = Math.min(i, Integer.MAX_VALUE - -low);  

            }  

            high = h;  

  

            cache = new Integer[(high - low) + 1];  

            int j = low;  

            for(int k = 0; k < cache.length; k++) //缓存区间数据  

                cache[k] = new Integer(j++);  

        }  

  

        private IntegerCache() {}  

    }  

  

    /**  

     * Returns a <tt>Integer</tt> instance representing the specified  

     * <tt>int</tt> value.  

     * If a new <tt>Integer</tt> instance is not required, this method  

     * should generally be used in preference to the constructor  

     * {@link #Integer(int)}, as this method is likely to yield  

     * significantly better space and time performance by caching  

     * frequently requested values.  

     *  

     * @param  i an <code>int</code> value.  

     * @return a <tt>Integer</tt> instance representing <tt>i</tt>.  

     * @since  1.5  

     */  

    public static Integer valueOf(int i) {  

        if(i >= -128 && i <= IntegerCache.high)  

            return IntegerCache.cache[i + 128];  

        else  

            return new Integer(i);  

    }  

这里的IntegerCache有一个静态的数组,在类加载的时候就已经将-128~127的Integer对象创建了,并保存在cache数组中,一旦调用Integer.valueOf方法,如果参数值在-128~127范围内,就会直接在cache中取Integer对象。否则会创建新的Integer对象。

再看其它的包装器:

Boolean:(全部缓存)
Byte:(全部缓存)

Character(<= 127缓存)

Short(-128 — 127缓存)
Long(-128 — 127缓存)

Float(没有缓存)
Doulbe(没有缓存)

因此对于垃圾回收来说:

[html] view
plaincopy

Integer i = 100;     

i = null;//will not make any object available for GC at all.  

这里没有垃圾回收的条件,因为Integer(100)这个对象任然存在于cache中。

如果对象不再-128~127的范围内,就会符合垃圾回收条件:

[html] view
plaincopy

Integer i = 10000;     

i = null;//will make the newly created Integer object available for GC.  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: