资讯专栏INFORMATION COLUMN

Integer的缓存

jay_tian / 767人阅读

摘要:基础系列的与方法类初始化顺序线程池如何弹性伸缩的几个要点的缓存什么场景下使用阻塞队列的使用及模式中的序本文主要简述的缓存。而如果大于或小于则它所指向的对象将符合垃圾回收的条件使用,在模式下,使用参数即可将的自动缓存区间设置为。

Java基础系列

Java的hashcode与equals方法

Java类初始化顺序

ThreadPoolExecutor线程池如何弹性伸缩

HashMap的几个要点

Integer的缓存

什么场景下使用阻塞队列

volatile的使用及DCL模式

try-catch-finally中的return

本文主要简述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= 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.
    }
参考

Integer.valueOf(String) 方法之惑

Java Integer(-128~127)值的==和equals比较产生的思考

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/65559.html

相关文章

  • Java Integer缓存策略

    摘要:整型对象在内部实现中通过使用相同的对象引用实现了缓存和重用。这种缓存策略仅在自动装箱的时候有用,使用构造器创建的对象不能被缓存。行的结果为而行则为。所以行的结果为而行为。中其他类似的缓存的缓存上限可以通过虚拟机参数修改,的缓存则没法修改。 Java5为Integer的操作引入了一个新的特性,用来节省内存和提高性能。整型对象在内部实现中通过使用相同的对象引用实现了缓存和重用。上面的规则默...

    endiat 评论0 收藏0
  • IntegerCache

    摘要:类实际上是中中的缓存类,目的是节省内存消耗,提高程序性能。而当堆内存中的对象存储非常多时,就有可能造成内存泄漏。使用频率高创建对象也就越多,堆内存中的对象也就越多,所以也就会可能发生上述中的内存溢出等问题。 面试题:问以下代码输出的结果是多少? public class IntegerTest { @Test public void test() { ...

    yiliang 评论0 收藏0
  • int和Integer深入分析

    摘要:对象头的另外一部分是类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。并不是所有的虚拟机实现都必须在对象数据上保留类型指针,换句话说,查找对象的元数据信息并不一定要经过对象本身,这点将在节讨论。 目录介绍 1.关于int和Integer的问题区别分析 2.Integer的值缓存的原理 2.1 Java 5 中引入缓存特性 2.2 Intege...

    Half 评论0 收藏0
  • 作为Java code copyer,你真了解Integer

    摘要:和的区别是的一种基本类型,则是对应的包装类。看到这里大概理解了为什么后两组的结果是了吧,因为他们本身不是基础类型,存储的不是数据值,比较的时候,是去比较引用。 Integer 和 int的区别 int是Java的一种基本类型,Integer则是对应的包装类。 Integer的默认值是null,int的默认值是0 Integer变量必须实例化后才能使用,而int变量不需要 Intege...

    LMou 评论0 收藏0
  • 源码|jdk源码之Object及装箱类型分析

    摘要:作为条件变量的的不仅可以认为内嵌了一把锁,还内嵌了一个条件变量。操作条件变量的函数将当前线程在条件变量上阻塞,一般是为了等待其他线程的某件事情执行完成。其它装箱类其它装箱类的代码这里就不分析了。重点关注下各装箱类的缓存范围。 jdk源码读到现在这里,重要的集合类也读了一部分了。集合类再往下读的话,就要涉及到两个方向。第一,是比较典型的但是不常用的数据结构,这部分我准备将数据结构复习、回...

    VioletJack 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<