为什么Integer类缓存值在-128到127之间?

时间:2014-01-03 05:16:59

标签: java caching

关于我之前的问题Why do == comparisons with Integer.valueOf(String) give different results for 127 and 128?,我们知道Integer class有一个缓存,可以存储-128127之间的值。

只是想知道为什么介于-128到127之间

Integer.valueOf() documentation声明缓存经常请求的值。但-128127之间的值是否经常被要求真实?我认为经常要求的值非常主观。
这有什么可能的原因吗?

从文档中也说明了: ..并且可以缓存此范围之外的其他值。
如何实现这一目标?

5 个答案:

答案 0 :(得分:104)

只是想知道,为什么介于-128和127之间?

可以缓存更大范围的整数 ,但至少必须缓存-128到127 之间的整数,因为它是Java Language Specification强制执行的(强调我的):

  

如果装箱的值p为真,假,字节或字符在\ u0000到\ u007f范围内,或 在-128和127之间的一个int或短号(包括)< / em> ,然后让r1和r2成为p的任意两次拳击转换的结果。始终是r1 == r2。

的情况

此要求的基本原理在同一段中解释:

  

理想情况下,装箱给定的原始值p,总会产生相同的参考 。实际上,使用现有的实现技术可能不可行。上述规则是一种务实的妥协。上面的最后一个条款要求将某些常见值装入无法区分的对象中。 [...]

     

这可以确保在大多数情况下,行为都是理想的行为,而不会造成过度的性能损失,尤其是在小型设备上 。例如,较少内存限制的实现可以缓存所有char和short值,以及-32K到+ 32K范围内的int和long值。


如何缓存此范围之外的其他值。

您可以使用-XX:AutoBoxCacheMax JVM选项,available Hotspot JVM Options列表中未实际记录该选项。但是在the comments inside the Integer class around line 590中提到了它:

  

缓存的大小可以由-XX:AutoBoxCacheMax=<size>选项控制。

请注意,这是特定于实现的,可能在其他JVM上可用,也可能不在。

答案 1 :(得分:21)

-128到127是默认大小。但javadoc还表示,-XX:AutoBoxCacheMax=<size>选项可以控制整数缓存的大小。请注意,它仅设置高值,低值始终为-128。此功能在1.6中引入。

至于-128到127的原因 - 这是字节值范围,很自然地将它用于非常小的缓存。

答案 2 :(得分:5)

缓存小整数的原因,如果你要问的是,许多算法在计算中使用小整数,因此避免这些值的对象创建开销往往是值得的。

然后问题就变成了要缓存的整数。同样,一般来说,使用常数值的频率会随着常数的绝对值的增加而减小 - 每个人都花费大量时间使用值1或2或10,相对较少的人使用值109非常集中;性能越少,取决于获得722的Integer的速度.Java选择分配256个时隙,跨越有符号字节值的范围。这个决定可能是通过分析当时存在的程序得出的,但也可能是纯粹随意的程序。这是一个合理的投资空间,可以快速访问(掩码以查明缓存范围内的值,然后快速查找表以访问缓存),它肯定会涵盖最常见的情况。

换句话说,我认为你的问题的答案是“它不像你想象的那样主观,但确切的界限在很大程度上是一个经验法则的决定......而且经验证据表明它是够好了。“

答案 3 :(得分:3)

可以缓存的最大高整数值可以通过系统属性进行配置,即java.lang.Integer.IntegerCache.high-XX:AutoBoxCacheMax)。缓存是使用数组实现的。

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

答案 4 :(得分:0)

当遇到Integer类并且总是在-128到127范围内时,最好将Integer对象转换为int值,如下所示。

<Your Integer Object>.intValue()