【发布时间】:2011-03-03 13:50:07
【问题描述】:
Java 数组可以包含的元素数量是否有限制?如果有,是什么?
【问题讨论】:
-
你接受了一个错误的答案,只是尝试分配这么长的数组(不,我没有内存不足)。
Java 数组可以包含的元素数量是否有限制?如果有,是什么?
【问题讨论】:
虽然很容易测试,但还没有看到正确的答案。
在最近的 HotSpot VM 中,正确答案是 Integer.MAX_VALUE - 5。一旦超越:
public class Foo {
public static void main(String[] args) {
Object[] array = new Object[Integer.MAX_VALUE - 4];
}
}
你得到:
Exception in thread "main" java.lang.OutOfMemoryError:
Requested array size exceeds VM limit
【讨论】:
MAX_VALUE-2 元素。这与我分配的内容无关,我真的很想知道 VM 可以使用这两个“东西”做什么(长度不适合 2 个字节)。
Integer.MAX_VALUE+1,你将有一个整数溢出。 Java 中的数组大小是int,而不是long;无论您在数组、字节或引用中存储什么数据类型。字符串只是对象引用。
Integer.MAX_VALUE - 2 = 2 147 483 645。如果使用-Xmx13G 运行,Java 会成功分配这样的数组。如果您通过 -Xmx12G,它会以 OutOfMemoryError: Java heap space 失败。
这(当然)完全依赖于虚拟机。
浏览 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) on 2010-05-09 添加;由 Chris Hegarty(甲骨文)审核。
因此,可能我们可以说最大的“安全”数是 2 147 483 639 (Integer.MAX_VALUE - 8) 并且“尝试分配更大的数组可能会导致在OutOfMemoryError"。
(是的,Buchholz 的独立声明不包括支持证据,所以这是一个计算得出的 appeal to authority. 即使在 OpenJDK 本身中,我们也可以看到类似 return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; 的代码,这表明 MAX_ARRAY_SIZE 还没有 真正使用。)
【讨论】:
-8?
-8 是由于保留的标题字将占用的字节数。
实际上有两个限制。一是数组可索引的最大元素,二是应用程序可用的内存量。根据可用内存量和其他数据结构使用的内存量,您可能会在达到最大可寻址数组元素之前达到内存限制。
【讨论】:
看这篇文章http://en.wikipedia.org/wiki/Criticism_of_Java#Large_arrays:
Java 因不支持超过 231-1(约 21 亿)个元素的数组而受到批评。这是语言的限制; Java 语言规范第 10.4 节指出:
数组必须由 int 值索引...尝试访问数组 具有长索引值的组件会导致编译时错误。
支持大型数组还需要更改 JVM。这种限制体现在诸如集合被限制为 20 亿个元素以及无法存储大于 2 GiB 的映射文件等领域。 Java 还缺乏真正的多维数组(通过单个间接访问连续分配的单个内存块),这限制了科学和技术计算的性能。
【讨论】:
数组是非负整数索引的,因此您可以访问的最大数组大小为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 拥有多少内存以及其中多少已分配给其他对象。
【讨论】:
我试图创建一个这样的字节数组
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
上面给出的值
线程“main”java.lang.OutOfMemoryError 中的异常:请求的数组大小超过了 VM 限制 在 Main.main(Main.java:6)
【讨论】:
array 的最大元素数是(2^31)−1 或2 147 483 647
【讨论】:
Integer.MAX_VALUE - 1 的数组,您将收到“java.lang.OutOfMemoryError: Requested array size exceeded VM limit”。 JDK 6 及更高版本的最大元素数为Integer.MAX_VALUE - 2 = 2 147 483 645。
是的,java 数组有限制。 Java 使用整数作为数组的索引,JVM 存储的最大整数是 2^32。因此您可以在数组中存储 2,147,483,647 个元素。
如果您需要超过最大长度,您可以使用两个不同的数组,但推荐的方法是将数据存储到文件中。因为在文件中存储数据没有限制。因为文件存储在您的存储驱动程序中,但数组存储在 JVM 中。 JVM 为程序执行提供了有限的空间。
【讨论】:
实际上,Java 的限制将其限制在 2^30-4 为 1073741820。不是 2^31-1。不知道为什么,但我在 jdk 上手动测试了它。 2^30-3 still throwing vm except
编辑:固定 -1 到 -4,在 windows jvm 上检查
【讨论】:
Java 数组有一个限制,因为它是一个整数数组,这意味着它的数组中最多有 2,147,483,647 个元素
【讨论】: