Максимальный размер Java-массивов?

Есть ли ограничение на количество элементов, которое может содержать массив Java? Если так, то, что это?

10 ответов

Решение

Не нашел правильного ответа, хотя это очень легко проверить.

В недавней виртуальной машине HotSpot правильный ответ: 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

Это (конечно) полностью 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;

который добавлен Мартином Буххольцем (Google) 2010-05-09; проверено Крисом Хегарти (Oracle).

Так что, вероятно, мы можем сказать, что максимальное "безопасное" число будет 2 147 483 639 (Integer.MAX_VALUE - 8) и "попытки выделить большие массивы могут привести к OutOfMemoryError ".

(Да, отдельное требование Бухгольца не включает подтверждающих доказательств, так что это расчетное обращение к авторитету. Даже в самом OpenJDK мы можем увидеть такой код return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; что показывает, что MAX_ARRAY_SIZE пока не имеет реального использования.)

На самом деле есть два ограничения. Во-первых, максимальный индексируемый элемент для массива и, во-вторых, объем памяти, доступный для вашего приложения. В зависимости от объема доступной памяти и объема, используемого другими структурами данных, вы можете достичь предела памяти, прежде чем достигнете максимального адресуемого элемента массива.

Продолжая эту статью http://en.wikipedia.org/wiki/Criticism_of_Java:

Java подверглась критике за то, что она не поддерживала массивы более чем 231-1 (около 2,1 миллиарда) элементов. Это ограничение языка; Спецификация языка Java, раздел 10.4, гласит, что:

Массивы должны быть проиндексированы значениями int... Попытка доступа к компоненту массива с длинным значением индекса приводит к ошибке времени компиляции.

Поддержка больших массивов также потребует изменений в JVM. Это ограничение проявляется в таких областях, как количество коллекций, ограниченное 2 миллиардами элементов, и невозможность хранения файлов карты размером более 2 ГиБ. В 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-битная серверная виртуальная машина (сборка 25.141-b16, смешанный режим)

Это работает только для x >= 2, что означает, что максимальный размер массива равен Integer.MAX_VALUE-2

Значения выше этого дают

Исключение в потоке "main" java.lang.OutOfMemoryError: Размер запрашиваемого массива превышает ограничение виртуальной машины в Main.main(Main.java:6)

Максимальное количество элементов array является (2^31)−1 или же 2 147 483 647

Да, есть ограничение на массив java. Java использует целое число в качестве индекса для массива, а максимальное целочисленное хранилище JVM составляет 2^32. поэтому вы можете хранить в массиве 2147483647 элементов.

Если вам нужно больше максимальной длины, вы можете использовать два разных массива, но рекомендуемый метод - сохранить данные в файл. потому что хранение данных в файле не имеет ограничений. потому что файлы хранятся в драйверах хранилища, а массив хранится в JVM. JVM предоставляет ограниченное пространство для выполнения программы.

Массив Java имеет ограничение, потому что это целочисленный массив, что означает, что он имеет до 2147483647 элементов в массиве

На самом деле это ограничение Java, ограничивающее 2^30-4 1073741820. Не 2^31-1. Не знаю почему, но я проверил это вручную на JDK. 2 ^ 30-3 до сих пор бросает вм кроме

Редактировать: исправлено от -1 до -4, проверено на windows jvm

Другие вопросы по тегам