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

DnR*_*DnR 80 java caching

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

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

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

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

ass*_*ias 104

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

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

如果被装箱的值p为真,假,字节或范围为\ u0000到\ u007f的字符,或者介于-128和127(含)之间的int或短数,则让r1和r2为结果p的任何两个拳击转换.始终是r1 == r2的情况.

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

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

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


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

您可以使用-XX:AutoBoxCacheMaxJVM选项,该选项在可用的Hotspot JVM选项列表中没有真正记录.然而,在Integer590行的类的注释中提到它:

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

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

  • 这是完整和最好的答案 - 该问题将 -128 到 127 范围与“经常请求的值”混淆,而实际上它们是出于不同的原因。-128 到 127 被缓存用于装箱。“经常请求的值”被缓存以提高性能。 (3认同)
  • @ niiraj874u当前实现使用驻留在内存中的缓存 - 每个"规范"整数都保存在该缓存中.因此,缓存所有整数意味着您可能必须在内存中保留最多2 ^ 32个整数(= 15+ GB),这是不合理的,即使在现代台式计算机上也是如此. (2认同)

Evg*_*eev 21

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

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

  • 是的,这就是为什么javadoc说..可以控制...我的Java是64位 (2认同)

kes*_*lam 5

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

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

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