Подтвердить что ты не робот

Может ли размер кучи JVM max быть динамическим?

Аргумент JVM -Xmx позволяет задавать максимальный размер кучи для JVM для некоторого значения. Но есть ли способ сделать это значение динамическим? Другими словами, я хочу сказать JVM "посмотрите, если вам это нужно, просто продолжайте брать ОЗУ из системы до тех пор, пока система не выйдет".

Двухчастная причина для запроса: Во-первых, приложение, о котором идет речь, может использовать очень широкий диапазон плунжеров в зависимости от того, что делает пользователь, поэтому концептуальные минимальные и максимальные значения довольно далеко друг от друга. Во-вторых, похоже, что JVM резервирует максимальное пространство кучи из виртуальной памяти во время загрузки. Это конкретное приложение запускается на довольно широком спектре аппаратных средств, поэтому выбор места для кучи "одного размера подходит всем" - это сложно, поскольку он должен быть достаточно низким, чтобы работать на аппаратных средствах младшего класса, но мы действительно чтобы иметь возможность использовать действительно мускулистые машины, если они доступны.

4b9b3361

Ответ 1

Но есть ли способ сделать это значение динамическим?

Буквально, нет. Максимальный размер кучи задается при запуске JVM и не может быть увеличен.

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

ИЗМЕНИТЬ

Стоит отметить, что существуют различные опции настройки -XX... GC, которые позволяют вам настроить способ, которым JVM расширяет кучу (до максимума).

Другая возможность состоит в том, чтобы разделить приложение на 2 части. Первая часть приложения делает всю необходимую подготовку для определения "размера" проблемы. Затем он выдает соответствующий максимальный размер кучи и запускает вторую часть приложения, голодную в памяти, в новой JVM.

  • Это работает, только если приложение может быть разделено так, как описано выше.

  • Это работает только в том случае, если можно вычислить размер проблемы. В некоторых случаях вычисление размера проблемы равносильно вычислению результата.

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

Ответ 2

Это не. Может, и, вероятно, должно:

-Xmx90%  // 90% of physical memory

Однако неявное значение по умолчанию, 100%, вероятно, не очень хорошая идея.

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

А язык ГК другой. Он собирает мусор только при необходимости. Пока есть комната, она не заботится о мусоре, задерживающемся вокруг. Если бы он мог получить всю память, которую хотел бы иметь, он получил бы всю память на компьютере.

Таким образом, программисту GC больше не нужно беспокоиться об утилизации каждого куска мусора, но он все равно должен иметь общее представление о допустимом соотношении мусора/живых объектов и инструктировать GC с помощью -Xmx.

Ответ 3

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

Я делаю именно это в OS X и Linux: у меня есть небольшая оболочка bash script, которая заботится о поиске правильных параметров JVM в зависимости от оборудования, на котором запущено приложение, а затем вызывает JVM.

Обратите внимание, что если вы предоставляете настольное приложение Java, вы можете использовать что-то вроде izpack для предоставления вашим пользователям установщика:

http://izpack.org

Я вообще не знаю, может ли Java Web Start использоваться для предоставления разных параметров JVM в зависимости от пользовательской конфигурации (возможно, нет, и JWS действительно очень долгое время, если вы планируете предоставлять профессионально выглядящее настольное приложение).

Ответ 4

Есть предложение по улучшению JDK (JEP) 8204088

"Максимальный предел динамической памяти"

который предлагает ввести CurrentMaxHeapSize:

Для динамического ограничения размера выделенной памяти (т.е. кучи size) может расти, вводится новая динамически определяемая пользователем переменная: CurrentMaxHeapSize. Эта переменная (определенная в байтах) ограничивает размер куча может быть расширена. Это может быть установлено во время запуска и изменено в во время выполнения. Независимо от того, когда оно определено, оно всегда должно иметь значение равно или меньше MaxHeapSize (Xmx - опция времени запуска, которая ограничивает размер кучи). В отличие от MaxHeapSize, CurrentMaxHeapSize, может динамически изменяться во время выполнения.

Ожидаемое использование - настроить JVM с очень консервативным Xmx. значение (которое, как показано, очень мало влияет на объем памяти) а затем контролировать, насколько большой куча использует CurrentMaxHeapSize динамический предел.

Пока нет признаков того, что эта функция активно работает, это относительно новый JEP (с 2018 года), так что я все равно буду помнить об этом.

А компания Jelastic (jelastic.com) сделала рабочий прототип JEP 8204088 для сборщика мусора G1:

Смотрите описание на http://mail.openjdk.java.net/pipermail/hotspot-gc-dev/2018-May/022077.html и список патчей для OpenJDKhttp://cr.openjdk.java.net/~tschatzl/jelastic/cmx/