Почему максимальный размер массива 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;
У меня есть некоторые связанные ответы, но я не выполнил свою задачу.
Некоторые люди дали некоторую логику, согласно документации "Some VMs reserve some header words in an array"
. Таким образом, для слов заголовка 8 вычитается. Но в этом случае, если заголовочные слова нуждаются в более чем 8, то каков будет ответ?
Прошу прояснить меня на этой основе. Благодарим за сотрудничество.
Ответы
Ответ 1
Прочитайте приведенную выше статью о Управление памятью Java, в которой четко указано
Я думаю, что это относится к ArrayList, так как это реализация Resizable array.
Анатомия объекта массива 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
Ответ 2
Размер заголовка объекта не может превышать 8 байт.
Для HotSpot:
Заголовок объекта состоит из a mark word
и a klass pointer
.
Знак имеет размер слова (4 байта на 32-битных архитектурах, 8 байт на 64-битных архитектурах) и
указатель klass имеет размер слова на архитектуре 32 bit
. В архитектуре 64 bit
указатель klass либо имеет размер слова, но также может иметь 4 byte
, если адреса кучи могут быть закодированы в этих 4 bytes
.
Эта оптимизация называется "сжатым oops" , и вы также можете управлять ею с помощью параметра UseCompressedOops.
Что находится в заголовке объекта java
Ответ 3
Значение - наихудший сценарий. Обратите внимание на комментарий:
Попытки выделить более крупные массивы могут привести к OutOfMemoryError
Он не говорит, будет просто. Если вы останетесь ниже этого значения, у вас не должно быть проблем (пока память доступна, конечно).
Вы можете посмотреть ответы на этот вопрос для получения дополнительной информации:
Почему я не могу создать массив с большим размером?