为什么 Integer 类缓存值的范围是 -128到127?

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

只是好奇,为什么是 在 -128和127之间

ValueOf ()文档 指出它是 缓存频繁请求的值 。但是 -128127之间的值是否经常被要求为实数?我认为 频繁请求的值是非常主观的。
这背后有什么可能的原因吗?

从文件中还指出: < em > “ . . 并且可以缓存这个范围之外的其他值。
如何才能做到这一点?

21086 次浏览

-128到127是默认大小。但 javadoc 还说,整数缓存 也许吧的大小由 -XX:AutoBoxCacheMax=<size>选项控制。注意,它只设置高值,低值总是 -128。这个特性是在1.6中引入的。

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

可以通过系统属性 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() {}
}

只是好奇,为什么是在 -128和127之间?

缓存范围更大的整数 ,但是至少缓存 -128和127之间的整数 必须的,因为它是由 Java 语言规范(强调地雷)授权的:

如果装箱的值 p 为 true、 false、一个字节或 u0000到 u007f 或 < strong > -128和127之间的 int 或 short 数(含) 范围内的一个字符,则设 r1和 r2是 p 的任意两个装箱转换的结果。R1 = = r2总是这种情况。

这一要求的理由在同一段中作了解释:

理想情况下,装箱给定的基元值 p,将始终产生相同的引用 。在实践中,使用现有的实现技术这可能是不可行的。上述规则是一种务实的妥协。上面的最后一个子句要求总是将某些公共值装箱成不可区分的对象。[...]

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


如何缓存这个范围之外的其他值?

您可以使用 -XX:AutoBoxCacheMax JVM 选项,可用的热点 JVM 选项列表中没有真正记录该选项。然而,在 Integer类中第590行左右的注释中提到:

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

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

缓存小整数的原因,如果你想知道的话,是因为许多算法在计算中使用小整数,所以避免这些值的对象创建开销是值得的。

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.

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

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

<Your Integer Object>.intValue()