«1. Обзор

В этом уроке мы узнаем причину ошибки «Не удалось зарезервировать достаточно места для кучи объектов», а также рассмотрим некоторые возможные сценарии.

2. Симптомы

«Не удалось зарезервировать достаточно места для кучи объектов» — это конкретная ошибка JVM, которая возникает, когда процесс Java не может создать виртуальную машину из-за нехватки памяти в работающей системе:

java -Xms4G -Xmx4G -jar HelloWorld.jar

Error occurred during initialization of VM
Could not reserve enough space for object heap
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

~ ~~ Обычно существует два возможных сценария возникновения ошибки. Во-первых, когда мы запускаем процесс Java с параметром ограничения максимального размера кучи (-Xmx), и значение больше, чем то, что процесс может иметь в операционной системе.

Ограничение размера кучи варьируется в зависимости от нескольких ограничений:

    Аппаратная архитектура (32/64 бит) Разрядная версия JVM (32/64 бит) используемая операционная система

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

3. Размер кучи

Пространство кучи Java — это пул выделения памяти для исполняемой программы Java, которым управляет сама JVM. По умолчанию пул распределения ограничен начальным и максимальным размером. Чтобы узнать больше о Heap Space в Java, ознакомьтесь с этой статьей здесь.

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

3.1. Максимальный размер кучи

Максимальный теоретический предел кучи для 32-разрядной и 64-разрядной JVM легко определить, взглянув на доступное пространство памяти: 2^32 (4 ГБ) для 32-разрядной JVM и 2^64 ( 16 эксабайт) для 64-битной JVM.

На практике из-за различных ограничений предел может быть намного ниже и зависит от операционной системы. Например, в 32-разрядных системах Windows максимальный размер кучи составляет от 1,4 до 1,6 ГБ. Напротив, в 32-разрядных системах Linux максимальный размер кучи может достигать 3 ГБ.

По этой причине, если приложению требуется большая куча, мы должны использовать 64-битную JVM. Однако с большой кучей у сборщика мусора будет больше работы, поэтому важно найти хороший баланс между размером кучи и производительностью.

3.2. Как контролировать ограничения размера кучи?

У нас есть два варианта управления ограничениями размера кучи JVM.

Во-первых, используя параметры командной строки Java при каждой инициализации JVM:

-Xms<size>    Sets initial Java heap size. This value must be a multiple of 1024 and greater than 1 MB.
-Xmx<size>    Sets maximum Java heap size. This value must be a multiple of 1024 and greater than 2 MB.
-Xmn<size>    Sets the initial and maximum size (in bytes) of the heap for the young generation.

К значению размера мы можем добавить букву k или K, m или M и g или G, чтобы указать килобайты, мегабайты и гигабайты. соответственно. Если буква не указана, используется единица измерения по умолчанию (байт).

-Xmn2g
-Xmn2048m
-Xmn2097152k
-Xmn2147483648

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

JAVA_OPTS="-Xms256m -Xmx512m"

Для получения дополнительной информации ознакомьтесь с нашим подробным руководством по параметрам JVM.

4. Заключение

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

Далее узнайте больше о потенциальных проблемах с памятью во время выполнения и о том, как их определить.