Integer的缓存

 阅读约 10 分钟

Java基础系列

本文主要简述Integer的缓存。

-128~127的Integer值比较

在-128~127的Integer值并且以Integer x = value;的方式赋值的Integer值在进行==和equals比较时,都会返回true,

  • 因为Java里面对处在在-128~127之间的Integer值,用的是原生数据类型int,会在内存里供重用,

  • 也就是说这之间的Integer值进行==比较时只是进行int原生数据类型的数值比较,而超出-128~127的范围,进行==比较时是进行地址及数值比较。

IntegerCache

/**
     * 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.  The size of the cache
     * may be controlled by the -XX:AutoBoxCacheMax=<size> option.
     * 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.
     */

    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) {
                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);
            }
            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() {}
    }

IntegerCache有一个静态的Integer数组,在类加载时就将-128 到 127 的Integer对象创建了,并保存在cache数组中,一旦程序调用valueOf 方法,如果i的值是在-128 到 127 之间就直接在cache缓存数组中去取Integer对象。

再看其它的包装器:

 Boolean:(全部缓存)
 Byte:(全部缓存)
 Character(<= 127缓存)
 Short(-128 — 127缓存)
 Long(-128 — 127缓存)
 Float(没有缓存)
 Doulbe(没有缓存)

实例代码

@Test
    public void testAutoBox(){
        System.out.println("<-128~127以内的Integer值,Integer x = value;的方式赋值!>");
        Integer i = 127;
        Integer j = 127;
        System.out.println("i=" + i + ",j =" + j);
        System.out.println("i == j:" + (i == j) + "<--比较-->i.equals(j):"+ i.equals(j));
        System.out.println("<-128~127以外的Integer值,Integer x = value;的方式赋值!>");
        Integer m = 128;
        Integer n = 128;
        System.out.println("m=" + m + ",n =" + n);
        System.out.println("m == n:" + (m == n) + "<--比较-->m.equals(n):"+ m.equals(n));
        System.out.println();
        System.out.println("<任意Integer值,Integer x = new Integer(value);的方式赋值!>");
        Integer x = new Integer(299);
        Integer y = new Integer(299);
        System.out.println("x=" + x + ",y =" + y);
        System.out.println("x == y:" + (x == y) + "<--比较-->x.equals(y):"+ x.equals(y));

        int a = 1000, b = 1000;
        System.out.println(a == b); //true

        Integer c = 1000, d = 1000;
        System.out.println(c == d); //false

        /**
         * 为了节省内存,对于下列包装对象的两个实例,当它们的基本值相同时,他们总是==:
         Boolean
         Byte
         Character, \u0000 - \u007f(7f是十进制的127)
         Integer, -128 — 127
         */
        Integer e = 100, f = 100;
        System.out.println(e == f); //true
    }

GC情况

/**
     * 这里的代码不会有对象符合垃圾回收器的条件,这儿的i虽然被赋予null,但它之前指向的是cache中的Integer对象,
     * 而cache没有被赋null,所以Integer(100)这个对象还是存在。
       而如果i大于127或小于-128则它所指向的对象将符合垃圾回收的条件

     使用Oracle/Sun JDK 6,在server模式下,使用-XX:AutoBoxCacheMax=NNN参数即可将Integer的自动缓存区间设置为[-128,NNN]。
     注意区间的下界固定在-128不可配置。
     在client模式下该参数无效。这个参数是server模式专有的,在c2_globals.hpp中声明,默认值是128;
     不过这个默认值在默认条件下不起作用,要手动设置它的值或者是开启-XX:+AggressiveOpts参数才起作用。
       -XX:AutoBoxCacheMax=20000
     */
    @Test
    public void testGc(){
        Integer i = 100;
        i = null;//will not make any object available for GC at all.

        Integer j = 10000;
        j = null;//will make the newly created Integer object available for GC.
    }

参考

阅读 3.2k更新于 2016-03-08

推荐阅读
code-craft
用户专栏

spring boot , docker and so on 欢迎关注微信公众号: geek_luandun

645 人关注
1539 篇文章
专栏主页
目录