Сколько памяти занимает массив java

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

В этом руководстве мы рассмотрим максимальный размер массива в Java.

2. Максимальный размер​

Программа Java может выделять массив только до определенного размера. Обычно это зависит от используемой JVM и платформы. Поскольку индекс массива — int, приблизительное значение индекса может быть 2^31 — 1. Исходя из этого приближения, мы можем сказать, что массив теоретически может содержать 2 147 483 647 элементов .

В нашем примере мы используем реализации OpenJDK и Oracle для Java 8 и Java 15 на компьютерах Linux и Mac. Результаты были одинаковыми на протяжении всего нашего тестирования.

В этом можно убедиться на простом примере:

 for (int i = 2; i >= 0; i--)    try    int[] arr = new int[Integer.MAX_VALUE - i];   System.out.println("Max-Size : " + arr.length);   > catch (Throwable t)    t.printStackTrace();   >   > 

При выполнении вышеуказанной программы на машинах Linux и Mac наблюдается аналогичное поведение. При выполнении с аргументами виртуальной машины -Xms2G -Xmx2G мы получим следующие ошибки:

 java.lang.OutOfMemoryError: Java heap space  at com.example.demo.ArraySizeCheck.main(ArraySizeCheck.java:8)   java.lang.OutOfMemoryError: Requested array size exceeds VM limit  at com.example.demo.ArraySizeCheck.main(ArraySizeCheck.java:8)   java.lang.OutOfMemoryError: Requested array size exceeds VM limit 

Обратите внимание, что первая ошибка отличается от двух последних. Последние две ошибки связаны с ограничением виртуальной машины, а первая связана с ограничением памяти в куче .

Теперь попробуем с аргументами ВМ -Xms9G -Xmx9G получить точный максимальный размер:

 Max-Size: 2147483645   java.lang.OutOfMemoryError: Requested array size exceeds VM limit  at com.example.demo.ArraySizeCheck.main(ArraySizeCheck.java:8)   java.lang.OutOfMemoryError: Requested array size exceeds VM limit  at com.example.demo.ArraySizeCheck.main(ArraySizeCheck.java:8) 

Результаты показывают, что максимальный размер составляет 2 147 483 645 .

Такое же поведение можно наблюдать для byte , boolean , long и других типов данных в массиве, и результаты будут такими же.

3. Поддержка массивов ​

ArraysSupport — это служебный класс в OpenJDK, который предлагает максимальный размер Integer.MAX_VALUE — 8 , чтобы он работал со всеми версиями и реализациями JDK .

4. Вывод​

В этой статье мы рассмотрели максимальный размер массива в Java.

Как обычно, все примеры кода, используемые в этом руководстве, доступны на GitHub.

Источник

Сколько места занимает массив?

Я имею в виду, если я создам 10 целых чисел и целочисленный массив из 10, будет ли какая-либо разница в занятом занятом пространстве. Я задал этот вопрос: мне нужно создать булевский массив из миллионов записей, поэтому я хочу понять, сколько места будет занимать массив.

ну, я хочу знать, если я создаю логический массив из миллионов записей, сколько места будет занимать массив

9 ответов

Массив целых чисел представлен как блок памяти для хранения целых чисел и заголовка объекта. Заголовок объекта обычно занимает 3 32-битных слова для 32-разрядной JVM, но это зависит от платформы. (Заголовок содержит некоторые биты флага, ссылку на дескриптор класса, пространство для информации об элементарной блокировке и длину фактического массива. Плюс добавление.)

Таким образом, массив из 10 int, вероятно, занимает область 13 * 4 байтов.

В случае с Integer[] каждый объект Integer имеет заголовок 2 слова и поле 1 слово, содержащее фактическое значение. Также вам нужно добавить в дополнение и 1 слово (или от 1 до 2 слов на 64-битной JVM) для справки. Обычно это 5 слов или 20 байтов на элемент массива. если некоторые объекты Integer не отображаются в нескольких местах массива.

  • Число слов, фактически используемых для ссылки на 64-битной JVM, зависит от того, используются ли «сжатые oops».
  • На некоторых JVM узлы кучи выделяются в кратных 16 байтах. которые раздувают использование пространства (например, указанное дополнение).
  • Если вы берете идентификатор хэш-кода объекта и выживаете в следующей сборке мусора, его размер завышается не менее чем на 4 байта для кэширования значения хэш-кода.
  • Эти числа относятся ко всем версиям и поставщикам, в дополнение к перечисленным выше источникам изменчивости.

@Thilo На самом деле не просто предсказать размер указателя. Из-за выравнивания JVM все еще может сойти с 4-байтовыми указателями. Это то, что я наблюдаю в моей системе.

@MarkoTopolnik: это здорово! Я немного переживала об этом, и когда я проверила тогда, я получила ответы, что указателям действительно нужно 8 байтов, если вы не включите дополнительную опцию сжатия. stackoverflow.com/questions/3733215/… Рад видеть, что это исправлено сейчас (это показалось немного чрезмерным).

В java у вас есть как Integer, так и int. Предположим, что вы ссылаетесь на int, массив ints считается объектом, а объекты имеют метаданные, поэтому массив из 10 ints будет занимать более 10 переменных int

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

EDIT: вам нужно понять, что разница между Boolean wrapper и boolean primitive type. Типы обертки обычно занимают больше места, чем примитивы. Поэтому для миссий записей старайтесь идти с примитивами.

Еще одна вещь, которую следует иметь в виду при работе с миссиями записи, как вы сказали, — это Java Autoboxing. Снижение производительности может быть значительным, если вы непреднамеренно используете его в функции, которая перемещает весь массив.

Разница может быть довольно большой, хотя, если это Integer[] vs int[] . В этом случае объекты-оболочки будут занимать большую часть пространства.

Согласовано. Ответ отредактирован. Но семантика массива займет ту же память, я думаю. Основное отличие заключается в объектах / элементах, хранящихся в массиве. Так что я не думаю, что я был не в порядке.

Аргумент типа обертки хорош, но не для булева , потому что есть только два возможных значения, поэтому будет много общего с указателем. Конечно, вам все равно нужно хранить четыре (или восемь) байта для ссылки, а не «просто» один для bool.

Некоторые грубые вычисления нижних границ:

Каждый int занимает четыре байта. = 40 байт для десяти

В массиве int берется четыре байта для каждого компонента плюс четыре байта для хранения длины плюс еще четыре байта для хранения ссылки на него. = 48 байтов (возможно, некоторое дополнение для выравнивания всех объектов с границами 8 байтов)

Целое число занимает не менее 8 байт, плюс еще четыре байта для хранения ссылки на него. = не менее 120 за десять

Массив Integer занимает по меньшей мере 120 байт для десяти целых чисел плюс четыре байта для длины, а затем, возможно, некоторое дополнение для выравнивания. Плюс четыре байта, чтобы сохранить ссылку на него. (@Marko сообщает, что он даже измерил около 28 байтов на каждый слот, так что это было бы 280 байтов для массива из десяти).

В 64-битной Java все указатели занимают восемь байтов вместо четырех, что делает разницу между примитивом и оболочкой еще больше.

Я измерял, что Integer[] полный экземпляров Integer, занимает в среднем 28 байт на слот (64-битная JVM). Интересным фактом является то, что он точно такой же, как массив Object s.

Он не должен плохо отражать учителя/интервьюера.

Насколько вы заботитесь о размере и выравнивании переменных в памяти, зависит от того, насколько результативен ваш код. Это важно, если ваше программное обеспечение обрабатывает транзакции (например, EFT/фондовый рынок).

Размер, выравнивание и упаковка ваших переменных в памяти могут влиять на удары/промахи кэша CPU, которые могут влиять на производительность вашего кода на коэффициент 100.

Неплохо, чтобы знать, что происходит на низком уровне, до тех пор, пока вы используете ответные меры, повышающие производительность.

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

Источник

Читайте также:  Write content to file in java
Оцените статью