java中的一组int作为32位值的块存储在内存中。 如何存储整数对象数组? 即
int[] vs. Integer[]
我想,Integer数组中的每个元素都是对Integer对象的引用,并且Integer对象具有对象存储开销,就像任何其他对象一样。
但是我希望JVM能够在整个引擎中做一些神奇的聪明才智,因为整数是不可变的并且存储它就像一组int。
我的希望是天真的吗? 在每个最后一盎司性能都很重要的应用程序中,Integer数组是否比int数组慢得多?
我知道没有VM会存储一个类似int []数组的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倍 。
性能开销也很大,主要有两个原因:
总而言之,在性能关键工作中使用int []将比在当前VM中使用Integer数组更快且内存效率更高,并且在不久的将来这种情况不会发生太大变化。
John Rose致力于JVM中的fixnums来解决这个问题。
我认为你的希望非常天真。 具体来说,它需要处理Integer可能为null的问题,而int不能。 仅这一点就足以存储对象指针。
也就是说,实际的对象指针将是一个不可变的int实例,特别是对于一个选择的整数子集。
它不会慢得多,但因为Integer []必须接受“null”作为条目而int []不必,所以会涉及一些书记,即使Integer []得到了一个INT []。
因此,如果每一个最后一盎司的性能都很重要,那么用户int []
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是否是正确的解决方案。