Java数组是否具有最大大小?

Liz*_*ard 203 java arrays

Java数组可以包含的元素数量是否有限制?如果是这样,它是什么?

Kev*_*ion 174

没有看到正确的答案,即使它很容易测试.

在最近的HotSpot VM中,正确的答案是Integer.MAX_VALUE - 5.一旦你超越了:

public class Foo {
  public static void main(String[] args) {
    Object[] array = new Object[Integer.MAX_VALUE - 4];
  }
}
Run Code Online (Sandbox Code Playgroud)

你得到:

Exception in thread "main" java.lang.OutOfMemoryError:
  Requested array size exceeds VM limit
Run Code Online (Sandbox Code Playgroud)

  • 我认为downvotes的想法是没有意义的,除非我们愿意低估简单而简单_Wrong_的答案.五个字节的差异在现实世界中是否真实重要,不,当然不是.但它让我感到担忧的是,人们愿意"权威地"给出一个答案,甚至没有试图看它是否真的有效.至于内存限制,好吧,DUH.就像你问我"你能吃多少葡萄?" 我说"嗯,这取决于我当时在冰箱里有多少." (52认同)
  • @Kevin Bourrillion:这似乎已经改变了,使用Oracle 1.7.0_07我可以分配到'MAX_VALUE-2`元素.这与我分配的内容无关,我真的很想知道VM可以使用两个"东西"(长度不适合2个字节). (16认同)
  • 你碰巧知道_why_它不会给你那五个字节?这是否总是发生在Java中,或者它只是与您的计算机的内存有关? (6认同)
  • JDK 6及更高版本中数组中元素的最大数量是`Integer.MAX_VALUE - 2` = 2 147 483 645.如果使用`-Xmx13G`运行它,Java会成功分配这样的数组.如果传递`-Xmx12G`,它将失败并出现'OutOfMemoryError:Java堆空间'. (6认同)
  • @TomášZato最新的`Integer.MAX_VALUE + 1`,你将有一个整数溢出.Java中的数组大小是`int`,而不是`long`; 无论您在数组,字节或引用中存储什么数据类型.字符串只是对象引用. (3认同)
  • @Pacerier,是的,内存地址索引是32位,并且有一个对象头+长度,所以它们仍然需要通过该32位索引进行寻址. (2认同)
  • @maaartinus,*对象头要大得多*对象头是(通常)8bytes + 4bytes长度.参考在32位系统上占用4个字节. (2认同)
  • 等等,内存不足。如果你只是给它更多的内存怎么办?我想知道没有这种限制的最大长度。在 C 和 Objective C 中,当您获得数组的长度时,它表示为 long。 (2认同)

Pac*_*ier 122

这(当然)完全取决于VM.

通过OpenJDK的7和8的源代码浏览java.util.ArrayList,.Hashtable,.AbstractCollection, .PriorityQueue,和.Vector,可以看到这个权利要求进行重复:

/**
 * Some VMs reserve some header words in an array.
 * Attempts to allocate larger arrays may result in
 * OutOfMemoryError: Requested array size exceeds VM limit
 */
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
Run Code Online (Sandbox Code Playgroud)

由Martin Buchholz(谷歌)于2010-05-09添加 ; 由Chris Hegarty(Oracle)审核.

所以, 也许 我们可以说,最大的"安全"的数目将是 2 147 483 639(Integer.MAX_VALUE - 8)和"尝试分配更大的阵列可能会导致OutOfMemoryError错误 ".

(是的,Buchholz的独立声明不包括支持证据,因此这是对权威的计算吸引力.即使在OpenJDK本身,我们也可以看到代码,如同return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;哪些节目MAX_ARRAY_SIZE尚未真正使用.)


tva*_*son 38

实际上有两个限制.一个是数组可索引的最大元素,另外两个是应用程序可用的内存量.根据可用内存量和其他数据结构使用的数量,您可能会在达到最大可寻址数组元素之前达到内存限制.


wor*_*ing 27

通过这篇文章http://en.wikipedia.org/wiki/Criticism_of_Java#Large_arrays:

Java因不支持超过2 31 -1(约21亿)元素的数组而受到批评.这是语言的限制; Java语言规范第10.4节规定:

数组必须由int值索引...尝试访问具有长索引值的数组组件会导致编译时错误.

支持大型阵列也需要更改JVM.这种限制表现在诸如集合被限制为20亿个元素以及无法存储大于2 GiB的映射文件的区域中.Java还缺少真正的多维数组(连续分配由单个间接访问的单个内存块),这限制了科学和技术计算的性能.

  • Java缺少多维数组的语法糖,但你仍然可以通过一点乘法"拥有"它们(除非数组的总大小超过上述限制) (5认同)
  • @kbolino 这是真的。我相信科学用户足够聪明,可以制作自己的多维数组 (2认同)

Dha*_*uka 10

数组是非负整数索引,因此您可以访问的最大数组大小Integer.MAX_VALUE.另一件事是你可以创建多大的数组.它取决于您可用的最大内存JVM和阵列的内容类型.每个数组元素都有它的大小,例如.byte = 1 byte,int = 4 bytes,Object reference = 4 bytes (on a 32 bit system)

因此,如果您的计算机上有1 MB可用内存,则可以分配一个byte[1024 * 1024]或多个数组Object[256 * 1024].

回答你的问题 - 你可以分配一个大小的数组(最大可用内存/数组项的大小).

总结 - 从理论上讲,数组的最大大小将是Integer.MAX_VALUE.实际上,它取决于您JVM拥有多少内存以及已经分配给其他对象的内存量.