整数数组如何在JVM内部存储? [英] How are Integer arrays stored internally, in the JVM?

查看:121
本文介绍了整数数组如何在JVM内部存储?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

java中的一个int数组存储为内存中32位值的块。如何存储整数对象数组? ie

An array of ints in java is stored as a block of 32-bit values in memory. How is an array of Integer objects stored? i.e.

int[] vs. Integer[]

我认为Integer数组中的每个元素都是对Integer对象的引用,并且Integer对象具有对象存储开销,就像任何其他对象一样。

I'd imagine that each element in the Integer array is a reference to an Integer object, and that the Integer object has object storage overheads, just like any other object.

我希望JVM能够在整个引擎中做一些神奇的聪明,因为整数是不可变的,并且就像一个整数数组一样存储它。

I'm hoping however that the JVM does some magical cleverness under the hood given that Integers are immutable and stores it just like an array of ints.

我的希望是天真的吗?在每个最后一盎司性能都很重要的应用程序中,Integer数组是否比int数组慢得多?

Is my hope woefully naive? Is an Integer array much slower than an int array in an application where every last ounce of performance matters?

推荐答案

我知道没有VM将存储一个Integer []数组,如int []数组,原因如下:

No VM I know of will store an Integer[] array like an int[] array for the following reasons:


  1. 可以有 null 数组中的整数对象,并且没有剩下的位用于在int数组中指示它。 VM可以将每个数组插槽的1位信息存储在hiden位数组中。

  2. 您可以在Integer数组的元素中进行同步。这是第一点要克服的难度,因为你必须为每个数组插槽存储一个监视器对象。

  3. 可以比较Integer []的元素的身份。例如,您可以通过 new 创建值为1的两个Integer对象,并将它们存储在不同的数组槽中,然后检索它们并通过==进行比较。这必然会导致错误,因此您必须将此信息存储在某处。或者你在某处保留对一个Integer对象的引用并使用它进行比较,你必须确保其中一个==比较是假的,一个是真的。这意味着对于优化的整数数组,对象标识的整个概念很难处理。

  4. 您可以将Integer []转换为例如Object []并将其传递给期望只有Object []的方法。这意味着处理Object []的所有代码现在也必须能够处理特殊的Integer []对象,使其变得越来越大。

  1. There can be null Integer objects in the array and you have no bits left for indicating this in an int array. The VM could store this 1-bit information per array slot in a hiden bit-array though.
  2. You can synchronize in the elements of an Integer array. This is much harder to overcome as the first point, since you would have to store a monitor object for each array slot.
  3. The elements of Integer[] can be compared for identity. You could for example create two Integer objects with the value 1 via new and store them in different array slots and later you retrieve them and compare them via ==. This must lead to false, so you would have to store this information somewhere. Or you keep a reference to one of the Integer objects somewhere and use this for comparison and you have to make sure one of the == comparisons is false and one true. This means the whole concept of object identity is quiet hard to handle for the optimized Integer array.
  4. You can cast an Integer[] to e.g. Object[] and pass it to methods expecting just an Object[]. This means all the code which handles Object[] must now be able to handle the special Integer[] object too, making it slower and larger.

考虑到所有这些因素,可能会创建一个特殊的Integer [],与 naive 实现相比可以节省一些空间,但额外的复杂性可能会影响很多其他代码,最终使它变慢。

Taking all this into account, it would probably be possible to make a special Integer[] which saves some space in comparison to a naive implementation, but the additional complexity will likely affect a lot of other code, making it slower in the end.

使用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

The overhead of using Integer[] instead of int[] can be quiet large in space and time. On a typical 32 bit VM an Integer object will consume 16 byte (8 byte for the object header, 4 for the payload and 4 additional bytes for alignment) while the Integer[] uses as much space as int[]. In 64 bit VMs (using 64bit pointers, which is not always the case) an Integer object will consume 24 byte (16 for the header, 4 for the payload and 4 for alignment). In addition a slot in the Integer[] will use 8 byte instead of 4 as in the int[]. This means you can expect an overhead of 16 to 28 byte per slot, which is a factor of 4 to 7 compared to plain int arrays.

性能开销也很大,主要有两个原因:

The performance overhead can be significant too for mainly two reasons:


  1. 因为你使用了更多的内存,所以你放了对内存子系统施加更大的压力,使其在Integer []的情况下更容易出现缓存未命中。例如,如果以线性方式遍历int []的内容,则缓存将在您需要时已经获取大部分条目(因为布局也是线性的)。但是在Integer数组的情况下,Integer对象本身可能在堆中随机分散,这使得缓存难以猜测下一个内存引用将指向的位置。

  2. 垃圾集合必须做更多的工作,因为使用了额外的内存,因为它必须分别扫描和移动每个Integer对象,而在int []的情况下,它只是一个对象,而对象的内容不必被扫描(它们不包含对其他对象的引用)。

总结一下,在性能关键工作中使用int []将与在当前虚拟机中使用整数数组相比,速度更快,内存效率更高,并且在不久的将来这种情况不会发生太大变化。

To sum it up, using an int[] in performance critical work will be both much faster and memory efficient than using an Integer array in current VMs and it is unlikely this will change much in the near future.

这篇关于整数数组如何在JVM内部存储?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆