Почему максимальный размер массива ArrayList равен Integer.MAX_VALUE - 8?
Я изучаю документацию по Java 8 для ArrayList
, Я получил, что максимальный размер массива определяется как Integer.MAX_VALUE - 8
означает 2^31 - 8 = 2 147 483 639. Затем я сосредоточился на том, почему вычитается 8 или why not less than 8
или же more than 8
вычитается?
/**
* The maximum size of array to allocate.
* 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;
Я получил несколько похожих ответов, но не выполнил свою задачу.
- Максимальный размер Java-массивов?
- Сколько данных в списке может храниться максимально
- Почему я не могу создать массив с большим размером?
Некоторые люди дали некоторую логику, что согласно документации "Some VMs reserve some header words in an array"
, Так что для слов заголовка вычитается 8. Но в этом случае, если заголовок слова нужно больше, чем 8, то каков будет ответ?
Пожалуйста, разъясните мне на этом основании. Заранее спасибо за ваше сотрудничество.
4 ответа
Прочитайте приведенную выше статью об управлении памятью Java, в которой четко говорится
Я думаю, что это относится к ArrayList, так как это реализация массива Resizable.
Анатомия объекта массива Java
Форма и структура объекта массива, такого как массив значений int, аналогичны стандартному объекту Java. Основное отличие состоит в том, что у объекта массива есть дополнительный фрагмент метаданных, который обозначает размер массива. Метаданные объекта массива, таким образом, состоят из: Class: указатель на информацию о классе, которая описывает тип объекта. В случае массива полей int это указатель на класс int[].
Флаги: набор флагов, которые описывают состояние объекта, включая хэш-код для объекта, если таковой имеется, и форму объекта (то есть является ли объект массивом).
Блокировка: информация о синхронизации для объекта, то есть, синхронизирован ли объект в данный момент.
Размер: размер массива.
максимальный размер
2^31 = 2,147,483,648
как массив, в котором он нуждается 8 bytes
в магазины размером 2,147,483,648
так
2^31 -8 (for storing size ),
поэтому максимальный размер массива определяется как Integer.MAX_VALUE - 8
Размер заголовка объекта не может превышать 8 байт.
Для HotSpot:
Заголовок объекта состоит из a mark word
а также a klass pointer
,
Слово метки имеет размер слова (4 байта в 32-битных архитектурах, 8 байтов в 64-битных архитектурах) и
указатель класса имеет размер слова на 32 bit
архитектуры. На 64 bit
В архитектурах указатель класса имеет размер слова, но также может иметь 4 byte
если адреса кучи могут быть закодированы в этих 4 bytes
,
Эта оптимизация называется "сжатый упс", и вы также можете управлять ей с помощью параметра UseCompressedOops.
Значение является худшим сценарием. Обратите внимание на комментарий:
Попытки выделить большие массивы могут привести к OutOfMemoryError
Это не говорит будет, просто может. Если вы останетесь ниже этого значения, у вас не должно возникнуть проблем (если, конечно, память доступна).
Вы можете посмотреть на ответы на этот вопрос для получения дополнительной информации:
Почему я не могу создать массив с большим размером?
Максимальный целочисленный размер: 2 ^31 - 1 = 2147483648 - 1
Integer.java:@Native public static final int MAX_VALUE = 0x7fffffff;