Максимальный размер 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