Почему максимальный размер массива 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;

Я получил несколько похожих ответов, но не выполнил свою задачу.

  1. Максимальный размер Java-массивов?
  2. Сколько данных в списке может храниться максимально
  3. Почему я не могу создать массив с большим размером?

Некоторые люди дали некоторую логику, что согласно документации "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.

Что находится в заголовке Java-объекта

Значение является худшим сценарием. Обратите внимание на комментарий:

Попытки выделить большие массивы могут привести к OutOfMemoryError

Это не говорит будет, просто может. Если вы останетесь ниже этого значения, у вас не должно возникнуть проблем (если, конечно, память доступна).

Вы можете посмотреть на ответы на этот вопрос для получения дополнительной информации:
Почему я не могу создать массив с большим размером?

Максимальный целочисленный размер: 2 ^31 - 1 = 2147483648 - 1

Integer.java:@Native public static final int MAX_VALUE = 0x7fffffff;

Другие вопросы по тегам