Java数组中元素的数量是否有限制?如果有,是多少?
使用
OpenJDK 64-Bit Server VM (build 15.0.2+7, mixed mode, sharing)
在 MacOS 上,答案似乎是 Integer.MAX_VALUE - 2
。一旦你超过了这个值:
cat > Foo.java << "END"
public class Foo {
public static void main(String[] args) {
boolean[] array = new boolean[Integer.MAX_VALUE - 1]; // too big
}
}
END
java -Xmx4g Foo.java
你将获得:
Exception in thread "main" java.lang.OutOfMemoryError:
Requested array size exceeds VM limit
Integer.MAX_VALUE+1
时,整数会发生溢出。在 Java 中,数组的大小为 int
类型,而不是 long
类型;无论你将什么数据类型存储在数组中,包括字节或引用类型。字符串只是对象引用。 - Has QUIT--Anony-MousseInteger.MAX_VALUE -2
=2 147 483 645。如果您使用-Xmx13G
运行Java,则可以成功分配这样大小的数组。如果您传递-Xmx12G
,它将出现OutOfMemoryError: Java heap space
错误。 - Alexey Ivanov当然,这完全取决于虚拟机。
浏览 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;
这个代码段是由Martin Buchholz (Google) 在2010年5月9日添加的; 由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
还没有一个真正的用途。)
实际上有两个限制。一个是数组可索引的最大元素,另一个是应用程序可用的内存量。根据可用内存量和其他数据结构使用的内存量,你可能会在达到最大可寻址数组元素之前达到内存限制。
数组必须由int值进行索引...使用long索引值访问数组组件会导致编译时错误。
要支持大型数组还需要更改JVM。这种限制在某些方面表现出来,例如集合被限制为20亿个元素以及无法内存映射大于2 GiB的文件。Java还缺乏真正的多维数组(由单个间接操作访问的连续分配的单个内存块),这限制了科学和技术计算的性能。
byte[]
byte[] bytes = new byte[Integer.MAX_VALUE-x];
System.out.println(bytes.length);
使用此运行配置:
-Xms4G -Xmx4G
并且 Java 版本:
Openjdk 版本 "1.8.0_141"
OpenJDK 运行时环境(版本 1.8.0_141-b16)
OpenJDK 64 位服务器 VM(版本 25.141-b16,混合模式)
仅适用于 x >= 2,这意味着数组的最大大小为 Integer.MAX_VALUE-2。
超出该值会导致以下错误:
Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit at Main.main(Main.java:6)
数组
的最大元素数量为(2^31)−1
或2 147 483 647
Integer.MAX_VALUE-1
的数组,否则会出现"java.lang.OutOfMemoryError: Requested array size exceeds VM limit"的错误。JDK6及以上版本中允许的最大元素数量为Integer.MAX_VALUE-2
= 2,147,483,645。 - Alexey Ivanov是的,Java 数组有限制。Java 使用整数作为数组的索引,JVM 可以存储的最大整数为 2^32,因此您可以在数组中存储 2,147,483,647 个元素。
如果需要超过最大长度,可以使用两个不同的数组,但推荐的方法是将数据存储到文件中。因为文件中存储的数据没有限制。因为文件存储在您的存储驱动器中,而数组存储在 JVM 中。JVM 为程序执行提供了有限的空间。
Integer.MAX_VALUE
的数组。 - Alexey Ivanov实际上这是Java的限制,将其限制在2^30-4即1073741820。而不是2^31-1。我不知道为什么,但我在JDK上手动测试过了。2^30-3仍然抛出vm异常
编辑:已修复为-4,在Windows JVM上进行了检查