java中的一个int数组存储为内存中32位值的块。如何存储整数对象数组?即。
int[] vs. Integer[]
我认为Integer数组中的每个元素都是对Integer对象的引用,并且Integer对象具有对象存储开销,就像任何其他对象一样。
我希望JVM在整个引擎中做一些神奇的聪明,因为整数是不可变的,并且就像一个整数数组一样存储它。
我的希望是天真的吗?在每个最后一盎司性能都很重要的应用程序中,Integer数组是否比int数组慢得多?
答案 0 :(得分:11)
我知道没有VM会将int []数组存储为Integer []数组,原因如下:
考虑到所有这些因素,可能会创建一个特殊的Integer [],与 naive 实现相比可以节省一些空间,但额外的复杂性可能会影响很多其他代码,最终使它变慢。
使用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 。
性能开销也很大,主要有两个原因:
总而言之,在性能关键工作中使用int []将比在当前VM中使用Integer数组更快且内存效率更高,并且在不久的将来这种情况不会发生太大变化。
答案 1 :(得分:3)
John Rose在JVM中fixnums工作以解决此问题。
答案 2 :(得分:1)
我认为你的希望非常天真。具体来说,它需要处理Integer可能为null的问题,而int不能。仅这一点就足以存储对象指针。
也就是说,实际的对象指针将是一个不可变的int实例,特别是对于一个选择的整数子集。
答案 3 :(得分:0)
它不会慢得多,但因为Integer []必须接受“null”作为条目而int []不必,所以会涉及一些书记,即使Integer []是由int []支持。
因此,如果每一次性能都很重要,那么用户int []
答案 4 :(得分:0)
Integer可以为null,而int不能的原因是因为Integer是一个成熟的Java对象,包含所有开销。因为你可以写
,所以有价值Integer foo = new Integer();
foo = null;
这对于说foo会有一个值有好处,但它还没有。
另一个区别是int
不执行溢出计算。例如,
int bar = Integer.MAX_VALUE;
bar++;
会快乐地增加条形,你最终得到一个非常负数,这可能不是你想要的第一个。
foo = Integer.MAX_VALUE;
foo++;
会抱怨,我认为这会是更好的行为。
最后一点是,作为Java对象的Integer带有对象的空间开销。我认为其他人可能需要在这里加入,但我相信每个对象消耗12个字节用于开销,然后用于数据存储本身的空间。如果你追求性能和空间,我想知道Integer是否是正确的解决方案。