我所知的任何VM都不会像int []数组那样存储Integer []数组,原因如下:
- 数组中可以 有空的 Integer对象,并且在int数组中没有剩余的用于指示此对象的位。但是,VM可以将每个阵列插槽的1位信息存储在隐藏位数组中。
- 您可以在Integer数组的元素中进行同步。首先,这很难克服,因为您必须为每个阵列插槽存储一个监视对象。
- 可以比较Integer []的元素的身份。例如,您可以通过 new 创建两个值为1的Integer对象,并将它们存储在不同的数组插槽中,然后检索它们并通过==比较它们。这必须导致错误,因此您必须将此信息存储在某处。或者,您在某处保留对一个Integer对象的引用,并使用该引用进行比较,并且必须确保==比较之一为false,而另一为true。这意味着对于 优化的 Integer数组,对象标识的整个概念很难处理。
- 您可以将Integer []强制转换为例如Object [],并将其传递给仅需要Object []的方法。这意味着所有处理Object []的代码现在也必须能够处理特殊的Integer []对象,从而使其变慢和变大。
考虑到所有这些因素,可能有可能制作一个特殊的Integer [],相比于 朴素的
实现,它可以节省一些空间,但是额外的复杂性可能会影响很多其他代码,最终使它变慢。
使用Integer []代替int
[]的开销在空间和时间上可能非常安静。在典型的32位VM上,一个Integer对象将消耗16字节(对象头为8字节,有效负载为4字节,对齐时为4个其他字节),而Integer
[]则使用与int
[]一样多的空间。在64位VM(使用64位指针,并非总是如此)中,一个Integer对象将消耗24个字节(标头为16个字节,有效负载为4个字节,对齐方式为4个字节)。另外,Integer
[]中的插槽将使用8个字节,而不是int []中的4个字节。这意味着您可以预期每个插槽的开销为 16到28 个字节,与普通int数组相比,这是
4到7倍 。
性能开销也可能很重要,主要有两个原因:
- 由于使用了更多的内存,因此给内存子系统带来了更大的压力,在Integer []的情况下,它更有可能发生高速缓存未命中。例如,如果您以线性方式遍历int []的内容,则高速缓存将在需要时已提取大多数条目(因为布局也是线性的)。但是在使用Integer数组的情况下,Integer对象本身可能会随机分散在堆中,这使缓存很难猜测下一个内存引用将指向的位置。
- 由于使用了额外的内存,垃圾收集必须做更多的工作,并且必须分别扫描和移动每个Integer对象,而对于int []来说,它只是一个对象,而对象的内容不必须进行扫描(它们不包含对其他对象的引用)。
综上所述,在当前性能要求较高的工作中使用int []会比在当前VM中使用Integer阵列更快,内存效率更高,而且在不久的将来这种变化不太可能发生。



