Максимальный размер Java-массивов? - PullRequest
196 голосов
/ 14 июня 2010

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

Ответы [ 8 ]

170 голосов
/ 14 июня 2010

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

В последней виртуальной машине 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
118 голосов
/ 05 декабря 2011

Это (конечно) полностью 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 еще не имеет реального использования.)

38 голосов
/ 14 июня 2010

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

26 голосов
/ 19 марта 2014

По этой статье http://en.wikipedia.org/wiki/Criticism_of_Java#Large_arrays:

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

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

Поддержка больших массивов также потребует изменений в JVM. Это ограничение проявляется в таких областях, как количество коллекций, ограниченное 2 миллиардами элементов, и невозможность хранения файлов карты размером более 2 ГиБ. В Java также отсутствуют настоящие многомерные массивы (непрерывно выделяемые отдельные блоки памяти, доступ к которым осуществляется по одной косвенной ссылке), что ограничивает производительность для научных и технических вычислений.

10 голосов
/ 22 июня 2015

Массивы индексируются неотрицательным целым числом, поэтому максимальный размер массива, к которому вы можете получить доступ, будет 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 и сколько уже выделено другим объектам.

3 голосов
/ 31 июля 2017

Я пытался создать байтовый массив, подобный этому

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)

Виртуальная 64-разрядная серверная виртуальная машина OpenJDK (сборка 25.141-b16, смешанный режим)

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

Значения выше, которые дают

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

1 голос
/ 27 декабря 2013

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

0 голосов
/ 01 февраля 2019

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...