Перейти к основному содержимому

Руководство по наиболее важным параметрам JVM

· 6 мин. чтения

1. Обзор

В этом кратком руководстве мы рассмотрим наиболее известные параметры, которые можно использовать для настройки виртуальной машины Java.

2. Явная память кучи — параметры Xms и Xmx

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

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

-Xms<heap size>[unit] 
-Xmx<heap size>[unit]

Здесь единица обозначает единицу, в которой память (обозначенная размером кучи ) должна быть инициализирована. Единицы могут быть отмечены как «g» для ГБ, «m» для МБ и «k» для КБ.

Например, если мы хотим выделить минимум 2 ГБ и максимум 5 ГБ для JVM, нам нужно написать:

-Xms2G -Xmx5G

Начиная с Java 8 размер метапространства не определен. Как только он достигает глобального предела, JVM автоматически увеличивает его. Однако, чтобы преодолеть ненужную нестабильность, мы можем установить размер метапространства с помощью:

-XX:MaxMetaspaceSize=<metaspace size>[unit]

Здесь размер метапространства обозначает объем памяти, который мы хотим выделить для метапространства .

Согласно рекомендациям Oracle , после общего объема доступной памяти вторым наиболее важным фактором является доля кучи, зарезервированная для молодого поколения. По умолчанию минимальный размер YG составляет 1310 МБ , а максимальный размер неограничен .

Мы можем назначить их явно:

-XX:NewSize=<young size>[unit] 
-XX:MaxNewSize=<young size>[unit]

3. Сбор мусора

Для лучшей стабильности приложения выбор правильного алгоритма сборки мусора имеет решающее значение.

JVM имеет четыре типа реализации GC :

  • Серийный сборщик мусора
  • Параллельный сборщик мусора
  • Сборщик мусора CMS
  • Сборщик мусора G1

Эти реализации могут быть объявлены со следующими параметрами:

-XX:+UseSerialGC
-XX:+UseParallelGC
-XX:+USeParNewGC
-XX:+UseG1GC

Подробнее о реализациях Garbage Collection можно прочитать здесь .

4. Ведение журнала сборщика мусора

Чтобы строго следить за работоспособностью приложения, мы всегда должны проверять производительность сборки мусора JVM . Самый простой способ сделать это — записать активность GC в удобочитаемом формате.

Используя следующие параметры, мы можем регистрировать активность сборщика мусора:

-XX:+UseGCLogFileRotation 
-XX:NumberOfGCLogFiles=< number of log files >
-XX:GCLogFileSize=< file size >[ unit ]
-Xloggc:/path/to/gc.log

UseGCLogFileRotation указывает политику чередования файлов журнала, как и log4j, s4lj и т. д. NumberOfGCLogFiles обозначает максимальное количество файлов журнала, которое может быть записано для одного жизненного цикла приложения. GCLogFileSize указывает максимальный размер файла. Наконец, loggc обозначает его местоположение.

Здесь следует отметить, что есть еще два доступных параметра JVM ( -XX:+PrintGCTimeStamps и -XX:+PrintGCDateStamps ), которые можно использовать для печати временной метки даты в журнале GC .

Например, если мы хотим назначить максимум 100 файлов журнала GC , каждый из которых имеет максимальный размер 50 МБ, и хотим сохранить их в папке « /home/user/log/» , мы можем использовать следующий синтаксис:

-XX:+UseGCLogFileRotation  
-XX:NumberOfGCLogFiles=10
-XX:GCLogFileSize=50M
-Xloggc:/home/user/log/gc.log

Однако проблема в том, что один дополнительный поток демона всегда используется для мониторинга системного времени в фоновом режиме. Такое поведение может стать узким местом в производительности; поэтому всегда лучше не играть с этим параметром в продакшене.

5. Обработка нехватки памяти

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

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

-XX:+HeapDumpOnOutOfMemoryError 
-XX:HeapDumpPath=./java_pid<pid>.hprof
-XX:OnOutOfMemoryError="< cmd args >;< cmd args >"
-XX:+UseGCOverheadLimit

Здесь следует отметить пару моментов:

  • HeapDumpOnOutOfMemoryError указывает JVM сбросить кучу в физический файл в случае OutOfMemoryError
  • HeapDumpPath обозначает путь, по которому должен быть записан файл; можно указать любое имя файла; однако, если JVM находит тег <pid> в имени, идентификатор текущего процесса, вызвавшего ошибку нехватки памяти, будет добавлен к имени файла в формате .hprof.
  • OnOutOfMemoryError используется для выдачи экстренных команд, которые должны быть выполнены в случае ошибки нехватки памяти; правильная команда должна использоваться в пространстве аргументов cmd. Например, если мы хотим перезапустить сервер, как только произойдет нехватка памяти, мы можем установить параметр:
-XX:OnOutOfMemoryError="shutdown -r"
  • UseGCOverheadLimit — это политика, ограничивающая долю времени, которое виртуальная машина проводит в сборке мусора, прежде чем будет ошибка OutOfMemory.

6. 32/64 бит

В среде ОС, где установлены как 32-, так и 64-разрядные пакеты, JVM автоматически выбирает 32-разрядные пакеты среды.

Если мы хотим установить 64-битную среду вручную, мы можем сделать это, используя следующий параметр:

-d<OS bit>

Бит ОС может быть 32 или 64 . Более подробную информацию об этом можно найти здесь .

7. Разное

  • -server : включает «Виртуальную точку доступа к серверу»; этот параметр используется по умолчанию в 64-битной JVM.

  • -XX:+UseStringDeduplication : Java 8u20 представил этот параметр JVM для сокращения ненужного использования памяти за счет создания слишком большого количества экземпляров одной и той же строки; это оптимизирует память кучи, уменьшая повторяющиеся значения String в один глобальный массив char[]

  • -XX:+UseLWPSynchronization : устанавливает LWP ( облегченный процесс ) — политику синхронизации на основе вместо синхронизации на основе потоков.

  • -XX:LargePageSizeInBytes : устанавливает большой размер страницы, используемый для кучи Java; принимает аргумент в ГБ/МБ/КБ; с большими размерами страниц мы можем лучше использовать аппаратные ресурсы виртуальной памяти; однако это может привести к увеличению размера пространства для PermGen , что, в свою очередь, может привести к уменьшению размера кучи Java.

  • -XX:MaxHeapFreeRatio : устанавливает максимальный процент свободной кучи после GC , чтобы избежать сжатия.

  • -XX:MinHeapFreeRatio : устанавливает минимальный процент свободной кучи после GC , чтобы избежать расширения; для мониторинга использования кучи вы можете использовать VisualVM, поставляемый с JDK.

  • -XX:SurvivorRatio : Соотношение размера пространства Эдема и – например, -XX:SurvivorRatio=6 устанавливает соотношение между каждым пространством выжившего и пространством Эдема как 1:6,

  • -XX:+UseLargePages : использовать большую страничную память, если она поддерживается системой; обратите внимание, что OpenJDK 7 имеет тенденцию к сбою при использовании этого параметра JVM. **

    **

  • -XX:+UseStringCache : включает кэширование часто выделяемых строк, доступных в пуле строк . **

    **

  • -XX:+UseCompressedStrings : использовать тип byte[] для объектов String , которые могут быть представлены в чистом формате ASCII

  • -XX:+OptimizeStringConcat : по возможности оптимизирует операции конкатенации строк . **

    **

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

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

Некоторые из них также можно использовать для целей отладки.

Если вы хотите более подробно изучить эталонные параметры, вы можете начать здесь .