【问题标题】:Do Java arrays have a maximum size?Java 数组有最大大小吗?
【发布时间】:2011-03-03 13:50:07
【问题描述】:

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

【问题讨论】:

标签: java arrays


【解决方案1】:

虽然很容易测试,但还没有看到正确的答案。

在最近的 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

【讨论】:

  • 我认为不赞成投票的想法是没有意义的,除非我们愿意反对简单明了的错误答案。五个字节的差异在现实世界中真的很重要吗,不,当然不重要。但令我担心的是,人们愿意“权威地”给出答案,甚至不去尝试看看它是否真的有效。至于内存限制,嗯,DUH。就像你问我“你能吃多少葡萄?”我说“嗯,这取决于我当时冰箱里有多少。”
  • 你知道为什么它不会给你那五个字节吗?这一定是在 Java 中总是会发生的事情,还是只是与您计算机的内存或其他什么有关?
  • @Kevin Bourrillion:这似乎已经改变,使用 Oracle 1.7.0_07 我最多可以分配 MAX_VALUE-2 元素。这与我分配的内容无关,我真的很想知道 VM 可以使用这两个“东西”做什么(长度不适合 2 个字节)。
  • @TomášZato 最新的Integer.MAX_VALUE+1,你将有一个整数溢出。 Java 中的数组大小是int,而不是long;无论您在数组、字节或引用中存储什么数据类型。字符串只是对象引用。
  • JDK 6 及更高版本中数组的最大元素个数为Integer.MAX_VALUE - 2 = 2 147 483 645。如果使用-Xmx13G 运行,Java 会成功分配这样的数组。如果您通过 -Xmx12G,它会以 OutOfMemoryError: Java heap space 失败。
【解决方案2】:

这(当然)完全依赖于虚拟机。

浏览 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
  • @Pacerier。不应该仅在使用 ArrayList 时应用此 MAX_ARRAY_SIZE 吗?这与使用像 int[] array = new int[some_value_here]; 这样的数组不同。不是吗?为什么 ArrayList 中定义的常量可以应用于普通数组(用 [] 定义)?他们在幕后是一样的吗?
  • @Tiago,不,代码本身与数组的最大大小无关。这只是一个声明。
  • @JohnWinter,引用指出“某些 VM 在数组中保留了一些标头词”。所以-8 是由于保留的标题字将占用的字节数。
【解决方案3】:

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

【讨论】:

    【解决方案4】:

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

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

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

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

    【讨论】:

    • Java 缺少用于多维数组的语法糖,但您仍然可以通过一点点乘法“拥有”它们(除非数组的总大小超过上述限制)
    • @kbolino 这是真的。我相信科学用户足够聪明,可以制作自己的多维数组
    【解决方案5】:

    数组是非负整数索引的,因此您可以访问的最大数组大小为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 拥有多少内存以及其中多少已分配给其他对象。

    【讨论】:

      【解决方案6】:

      我试图创建一个这样的字节数组

      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)

      【讨论】:

        【解决方案7】:

        array 的最大元素数是(2^31)−12 147 483 647

        【讨论】:

        • Java 无法分配大小为Integer.MAX_VALUE - 1 的数组,您将收到“java.lang.OutOfMemoryError: Requested array size exceeded VM limit”。 JDK 6 及更高版本的最大元素数为Integer.MAX_VALUE - 2 = 2 147 483 645。
        【解决方案8】:

        是的,java 数组有限制。 Java 使用整数作为数组的索引,JVM 存储的最大整数是 2^32。因此您可以在数组中存储 2,147,483,647 个元素。

        如果您需要超过最大长度,您可以使用两个不同的数组,但推荐的方法是将数据存储到文件中。因为在文件中存储数据没有限制。因为文件存储在您的存储驱动程序中,但数组存储在 JVM 中。 JVM 为程序执行提供了有限的空间。

        【讨论】:

          【解决方案9】:

          实际上,Java 的限制将其限制在 2^30-4 为 1073741820。不是 2^31-1。不知道为什么,但我在 jdk 上手动测试了它。 2^30-3 still throwing vm except

          编辑:固定 -1 到 -4,在 windows jvm 上检查

          【讨论】:

          • 您使用的是 32 位 JVM。使用 64 位 JVM,JVM 限制将接近 2^31。 (你还需要可用的堆空间,这不是默认的,并且会受到你的物理内存的影响。)
          【解决方案10】:

          Java 数组有一个限制,因为它是一个整数数组,这意味着它的数组中最多有 2,147,483,647 个元素

          【讨论】:

            猜你喜欢
            • 2011-03-03
            • 1970-01-01
            • 2017-07-23
            • 1970-01-01
            • 2010-10-29
            • 2023-03-08
            相关资源
            最近更新 更多