Java 为什么整数类缓存范围在 -128 到 127 之间的值?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20897020/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 05:05:31  来源:igfitidea点击:

Why Integer class caching values in the range -128 to 127?

javacaching

提问by DnR

Regarding my previous Question, Why do == comparisons with Integer.valueOf(String) give different results for 127 and 128?, we know that Integerclasshas a cache which stores values between -128and 127.

关于我之前的问题,为什么 == 与 Integer.valueOf(String) 的比较会给出 127 和 128 的不同结果?,我们知道它Integerclass有一个缓存,用于存储-128和之间的值127

Just wondering, why between -128 and 127?

只是想知道,为什么在 -128 和 127 之间

Integer.valueOf() documentationstated that it "caching frequently requested values". But does values between -128and 127are frequently requested for real? I thought frequently requested valuesare very subjective.
Is there any possible reason behind this?

Integer.valueOf() 文档声明它缓存频繁请求的值。但是-128和之间的值127是否经常被请求为真实值?我认为经常要求的值是非常主观的。
这背后有什么可能的原因吗?

From the documentation also stated: "..and may cache other values outside of this range."
How is this can be achieved?

从文档中还指出:..并且可能缓存此范围之外的其他值。
这是如何实现的?

采纳答案by assylias

Just wondering, why between -128 and 127?

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

A larger range of integers maybe cached, but at least those between -128 and 127 mustbe cached because it is mandated by the Java Language Specification(emphasis mine):

整数的较大范围可以被高速缓存,但至少那些-128和127之间必须被高速缓存,因为它由经授权Java语言规范(重点煤矿):

If the value p being boxed is true, false, a byte, or a char in the range \u0000 to \u007f, or an int or short number between -128 and 127 (inclusive), then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.

如果被装箱的值 p 是真、假、一个字节或一个 \u0000 到 \u007f 范围内的字符,或者一个 int 或介于 -128 和 127(含)之间的短数,则让 r1 和 r2 为p 的任意两个拳击转换。r1 == r2 总是如此。

The rationale for this requirement is explained in the same paragraph:

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

Ideally, boxing a given primitive value p, would always yield an identical reference. In practice, this may not be feasible using existing implementation techniques. The rules above are a pragmatic compromise. The final clause above requires that certain common values always be boxed into indistinguishable objects. [...]

This ensures that in most common cases, the behavior will be the desired one, without imposing an undue performance penalty, especially on small devices. Less memory-limited implementations might, for example, cache all char and short values, as well as int and long values in the range of -32K to +32K.

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

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



How can I cache other values outside of this range.?

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

You can use the -XX:AutoBoxCacheMaxJVM option, which is not really documented in the list of available Hotspot JVM Options. However it is mentioned in the comments inside the Integerclass around line 590:

您可以使用-XX:AutoBoxCacheMaxJVM 选项,该选项并未真正记录在可用的 Hotspot JVM 选项列表中。但是,在Integer590 行附近的类的评论中提到了它:

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

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

Note that this is implementation specific and may or may not be available on other JVMs.

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

回答by Evgeniy Dorofeev

-128 to 127 is the default size. But javadoc also says that the size of the Integer cache may becontrolled by the -XX:AutoBoxCacheMax=<size>option. Note that it sets only high value, low value is always -128. This feature was introduced in 1.6.

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

As for why -128 to 127 - this is byte value range and it is natural to use it for a very small cache.

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

回答by theexamtime

Max high integer value that can be cached can be configured through system property i.e java.lang.Integer.IntegerCache.high(-XX:AutoBoxCacheMax) . The cache is implemented using an array.

可以缓存的最大整数值可以通过系统属性 ie 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() {}
}

回答by keshlam

The reason for caching small integers, if that's what you're asking, is that many algorithms use small integers in their calculations, so avoiding the object-creation overhead for these values tends to be worthwhile.

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

The question then becomes which Integers to cache. Again, speaking in general, the frequency with which constant values are used tends to decrease as the absolute value of the constant increases -- everyone spends a lot of time using the values 1 or 2 or 10, relatively few few use the value 109 very intensively; fewer will have performance depend on how quickly one can obtain an Integer for 722.. Java chose to allocate 256 slots spanning the range of a signed byte value. This decision may have been informed by analyzing programs in existence at the time, but is just as likely to have been a purely arbitrary one. It's a reasonable amount of space to invest, it can be accessed rapidly (mask to find out if the value's in the cache's range, then a quick table lookup to access the cache), and it will definitely cover the most common cases.

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

In other words, I think the answer to your question is "it isn't as subjective as you thought, but the exact bounds are largely a rule-of-thumb decision ... and experiemental evidence has been that it was good enough."

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

回答by Teja

When you encounter with Integer class and always boxed within the range -128 to 127 it's always better to convert the Integer object into int value as below.

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

<Your Integer Object>.intValue()