Конфигурация производительности Java-машины

Выбор java-машины

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

Основные концепции конфигурирования производительности

Конфигурирование производительности java-машины сводится к управлению ее памятью и garbage collector (сборщиком мусора).

Объект содержится в памяти java-машины до тех пор, пока на него есть ссылки. Если на объект нет ссылок, он удаляется из памяти специальным процессом, запускаемым garbage collector (сборщиком мусора) по определенному алгоритму. Запуск и работа этого процесса называется "сборка мусора".

Модель памяти java представлена несколькими разделами:

  • heap (куча) — хранятся объекты, создаваемые приложением.

    • young generation (молодое поколение) — попадают объекты при создании;
    • old generation (старое поколение) — перемещаются объекты, пережившие несколько сборок мусора.
  • metaspace — специальный раздел, в котором хранятся java-классы, методы и прочие объекты.

В heap периодически работает garbage collector, который периодически освобождается память под новые объекты.

Если garbage collector не может освободить достаточно памяти для новых объектов (объектов, на которые есть ссылки, слишком много), то приложение завершает работу с ошибкой OutOfMemoryError. Эта же ошибка возникает, если в metaspace не хватит места для расположения новых объектов. Объем занимаемой памяти в metaspace не растет с увеличением нагрузки на приложение, поэтому достаточно один раз установить этому разделу памяти разумный предел.

Если garbage collector еще может освобождать память, но освобождает ее в объеме, который быстро занимается новыми объектами, то наблюдается падение производительности приложения: частые, продолжительные зависания, связанные с тем, что при "сборке мусора" все рабочие потоки приложения останавливаются и наблюдается высокая нагрузка на процессор сервера.

Исходя из вышеописанного следует выделять достаточно памяти для heap java.

Java-опции для конфигурирования производительности java-машины

Конфигурирование производительности java-машины проводится с помощью java-опций запуска приложения.

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

Конфигурирование производительности java-машины. Linux

Опции перечисляются в файле setenv.sh в значении переменной CATALINA_OPTS.

CATALINA_OPTS="-server
-Dfile.encoding=UTF-8
-Xms4096m
-Xmx4096m"

Значения по умолчанию для java-опций и версию java-машины можно узнать, выполнив в консоли сервера команду:

java -XX:+PrintFlagsFinal -version

Группа java-опций для работы и мониторинга приложения

  • -server — явно указывает использование серверной версии виртуальной машины java (Java HotSpot Server VM), данная версия специально оптимизирована для выполнения приложения на сервере.
  • -Xms — (InitialHeapSize) объем памяти, изначально выделенный операционной системой под heap java-машины. На production-серверах рекомендуется устанавливать значение параметра, равное значению -Xmx, чтобы избежать возможности в swap.
  • -Xmx — (MaxHeapSize) максимальный объем памяти, которая может быть выделена операционной системой под heap java-машины.
  • -XX:MaxMetaspaceSize — максимальный объем памяти, которая может быть выделена под Metaspace операционной системой.
  • -XX:ReservedCodeCacheSize — максимальный объем памяти для кэша динамически скомпилированного кода Java. Обычно значения по умолчанию достаточно. Если возникают проблемы с производительностью, а используемый объем кэша подходит к пределу или в логах Tomcat замечены предупреждения "VM warning: CodeCache is full. Compiler has been disabled", то следует вручную поднять лимит.
  • -XX:-UseCompressedClassPointers — выключает сжатие указателей на классы, что экономит использование памяти Non Heap. При этом работающее сжатие указателей сэкономило бы меньше памяти из-за сравнительно небольшого объема Metaspace, используемого приложением.
  • -Xlog:gc: — в качестве значения указывается путь до лога сборок мусора java.

    Для Linux

    На linux-сервере для того, чтобы лог не переписывался при перезапуске, можно указать путь с датой и временем в названии лога, например, /opt/naumen/nausd4/tomcat/logs/gc.log.$(date +%Y%m%d_%H%M)

Группа java-опций, обеспечивающих мониторинг работы приложения в реальном времени с помощью технологии Java Management Extensions (JMX) с использованием утилит jconsole, jvisualvm

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

  • -Dcom.sun.management.jmxremote.port=8999 — порт, по которому можно будет подключиться.
  • -Dcom.sun.management.jmxremote.authenticate=false — возможность подключения к приложению без авторизации. Если для безопасности планируется назначить логин и пароль на подключение по jmx, следует воспользоваться инструкцией Tomcat 9.
  • -Dcom.sun.management.jmxremote.ssl=false

Группа опций для включения автоматического снимка памяти приложения при ошибке "OutOfMemoryError"

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

Опции для снимка памяти приложения рекомендуется включать только по просьбе специалистов компании NAUMEN.

  • -XX:+HeapDumpOnOutOfMemoryError — включает автоматический снимок памяти приложения при ошибке "OutOfMemoryError".
  • -XX:HeapDumpPath =/opt/nausd4/ — указывает путь, по которому будет создан файл со снимком heapDump.