it-roy-ru.com

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

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

193
Lizard

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

В недавней виртуальной машине 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
165
Kevin Bourrillion

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

118
Pacerier

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

38
tvanfosson

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

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

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

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

25
working

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

10
Dhanuka

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

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 VM (сборка 25.141-b16, смешанный режим)

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

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

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

3
Vasilis Nicolaou

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

1
Baby

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

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

0
Ferned