Ранее мы изучили всю серию JVM, и конечная цель состоит не только в том, чтобы понять основы JVM, но и в том, чтобы подготовиться к настройке производительности JVM. Эта статья поможет вам узнать о настройке производительности JVM.
настройка производительности
Настройка производительности включает несколько уровней, таких как настройка архитектуры, настройка кода, настройка JVM, настройка базы данных, настройка операционной системы и т. д.
Настройка архитектуры и настройка кода являются основой настройки JVM, среди которых настройка архитектуры оказывает наибольшее влияние на систему.
Настройка производительности в основном выполняется в соответствии со следующими этапами: уточнение целей оптимизации, обнаружение узких мест в производительности, выполнение настройки производительности, получение данных с помощью инструментов мониторинга и статистики данных и подтверждение достижения целей.
Когда следует настраивать JVM
В следующих ситуациях вам необходимо рассмотреть возможность настройки JVM:
- Память кучи (старого поколения) продолжает увеличиваться до установленного максимального значения памяти;
- Полная сборка мусора бывает часто;
- Время паузы GC слишком велико (более 1 секунды);
- Исключения памяти, такие как OutOfMemory, возникают в приложении;
- Приложение использует локальный кеш и занимает много места в памяти;
- Пропускная способность и скорость отклика системы низкие или ухудшились.
Основные принципы настройки JVM
Настройка JVM — это средство, но не все проблемы можно решить с помощью настройки JVM, поэтому при настройке JVM мы должны руководствоваться некоторыми принципами:
- Большинство приложений Java не требуют оптимизации JVM;
- Большинство причин проблем GC вызваны проблемами на уровне кода (code level);
- Прежде чем выходить в интернет, вам следует подумать об оптимальной настройке параметров JVM машины;
- уменьшить количество создаваемых объектов (уровень кода);
- Сокращение использования глобальных переменных и больших объектов (на уровне кода);
- Отдавайте приоритет настройке архитектуры и настройке кода, а оптимизация JVM является крайней мерой (код, уровень архитектуры);
- Лучше анализировать ситуацию с GC для оптимизации кода, чем оптимизировать параметры JVM (уровень кода);
Благодаря вышеизложенным принципам мы выяснили, что, по сути, самый эффективный метод оптимизации — это оптимизация на уровне архитектуры и кода, а оптимизация JVM — это крайняя мера, которую также можно назвать последней «выжимкой» сервера. конфигурация.
Цели настройки JVM
Конечная цель настройки состоит в том, чтобы приложение использовало наименьшее потребление оборудования для обеспечения большей пропускной способности. Настройка JVM в основном направлена на оптимизацию производительности сборки сборщика мусора, чтобы приложения, работающие на виртуальных машинах, могли использовать меньше памяти и задержек для получения большей пропускной способности.
- Задержка: низкие паузы GC и низкая частота GC;
- низкое использование памяти;
- высокая пропускная способность;
Среди них улучшение производительности любого атрибута происходит почти за счет снижения производительности других атрибутов, чего нельзя достичь одновременно. Он определяется в зависимости от его важности в бизнесе.
Цели количественной оценки настройки JVM
Ниже приведены некоторые справочные примеры количественных целей для настройки JVM:
- Использование памяти кучи
- Использование памяти старого поколения
- средняя пауза
- Полный сбор мусора умножается на 0 или средний интервал паузы >= 24 часа;
Примечание. Цели количественной оценки настройки JVM для разных приложений различаются.
Шаги для настройки JVM
Как правило, настройку JVM можно выполнить с помощью следующих шагов:
- Проанализируйте журналы GC и файлы дампа, определите, нужна ли оптимизация, и выявите узкие места;
- Определить цели количественного определения настройки JVM;
- Определить параметры настройки JVM (скорректированные в соответствии с историческими параметрами JVM);
- Настройка таких показателей, как память, задержка и пропускная способность по очереди;
- Сравните и обратите внимание на различия до и после настройки;
- Непрерывный анализ и корректировка до тех пор, пока не будет найдена подходящая конфигурация параметров JVM;
- Найдите наиболее подходящие параметры, примените их ко всем серверам и отслеживайте.
В приведенных выше шагах операции некоторые шаги требуют выполнения нескольких итераций. Как правило, это начинается с удовлетворения требований программы к использованию памяти, затем следуют требования к временной задержке и, наконец, требования к пропускной способности.Необходимо постоянно оптимизировать на основе этого шага.Каждый шаг является основой для следующего шага, который необратимый.
параметры JVM
Наиболее важным инструментом для настройки JVM являются параметры JVM. Давайте сначала посмотрим на параметры JVM.
Параметры -XX называются нестабильными параметрами.Установки таких параметров могут легко привести к различиям в производительности JVM и сделать JVM чрезвычайно нестабильной. Если такие параметры установлены разумно, производительность и стабильность JVM будут значительно улучшены.
Правила синтаксиса нестабильного параметра включают следующее.
Значение параметра логического типа:
- -XX:+ '+' означает включение этой опции
- -XX:- '-' означает выключение этой опции
Значение параметра числового типа:
- -XX:= Установите значение числового типа для параметра, за которым может следовать единица измерения, например: 'm' или 'M' для мегабайтов, 'k' или 'K' для килобайтов, 'g' или 'G ' для гигабайт байт. 32K — это тот же размер, что и 32768.
Значение параметра строкового типа:
- -XX:= Устанавливает для опции строковое значение, обычно используемое для указания файла, пути или списка команд. Например: -XX:HeapDumpPath=./dump.core
Разбор и настройка параметров JVM
Например, следующие примеры параметров:
-Xmx4g –Xms4g –Xmn1200m –Xss512k -XX:NewRatio=4 -XX:SurvivorRatio=8 -XX:PermSize=100m -XX:MaxPermSize=256m -XX:MaxTenuringThreshold=15
Выше приведен пример Java 7 и предыдущих версий В Java 8 параметры постоянного поколения -XX:PermSize и -XX:MaxPermSize недействительны. Это было рассмотрено в предыдущей главе.
Разбор параметров:
- -Xmx4g: максимальный объем кучи составляет 4 ГБ.
- -Xms4g: инициализировать размер кучи до 4 ГБ.
- -Xmn1200m: установите размер молодого поколения на 1200 МБ. Когда молодое поколение увеличивается, размер старого поколения уменьшается. Это значение сильно влияет на производительность системы, и Sun официально рекомендует устанавливать его равным 3/8 всей кучи.
- -Xss512k: установить размер стека для каждого потока. После JDK5.0 размер стека каждого потока составляет 1 МБ, а ранее размер стека каждого потока составлял 256 КБ. Его следует настроить в соответствии с объемом памяти, требуемым потоками приложения. В той же физической памяти уменьшение этого значения может создать больше потоков. Однако операционная система по-прежнему имеет ограничение на количество потоков в процессе, которое не может генерироваться бесконечно, а значение опыта составляет около 3000–5000.
- -XX:NewRatio=4: установить соотношение молодого поколения (включая Эдем и две области выживших) к старому поколению (исключая постоянное поколение). Если установлено значение 4, соотношение между молодым поколением и старым поколением составляет 1:4, а на молодое поколение приходится 1/5 всего стека.
- -XX:SurvivorRatio=8: установить соотношение размеров области Эдема к области выживших в молодом поколении. Если установлено значение 8, соотношение двух областей Выживших к одной области Эдема составляет 2:8, а на одну область Выживших приходится 1/10 всего молодого поколения.
- -XX:PermSize=100m: Инициализировать размер постоянного поколения до 100 МБ.
- -XX:MaxPermSize=256m: Установите постоянный размер генерации на 256 МБ.
- -XX:MaxTenuringThreshold=15: установить максимальный возраст мусора. Если установлено значение 0, объекты молодого поколения напрямую входят в старое поколение, не проходя через область Survivor. Для приложений с большим количеством старых поколений можно повысить эффективность. Если для этого значения установлено большее значение, объекты молодого поколения будут реплицироваться несколько раз в области Survivor, что может увеличить время выживания объектов в молодом поколении и повысить вероятность того, что они будут переработаны в молодом поколении. .
Если параметры нового поколения, старого поколения и постоянного поколения не указаны, виртуальная машина автоматически выберет соответствующие значения, а также будет автоматически скорректирована с учетом системных накладных расходов.
Настраиваемые параметры:
-Xms: Инициализировать размер кучи памяти, по умолчанию 1/64 физической памяти (менее 1 ГБ).
-Xmx: максимальная память кучи. По умолчанию (параметр MaxHeapFreeRatio можно настроить), когда свободная память кучи больше 70%, JVM уменьшит кучу до минимального предела -Xms.
-Xmn: Размер нового поколения, включая область Эдема и 2 области Выживших.
-XX:SurvivorRatio=1: Соотношение площади Эдема к площади Выживших составляет 1:1.
-XX:MaxDirectMemorySize=1G: Прямая память. Это значение можно увеличить, сообщив об ошибке java.lang.OutOfMemoryError: исключение прямой буферной памяти.
-XX:+DisableExplicitGC: отключить явные вызовы System.gc() во время выполнения для запуска полного GC.
Примечание. Механизм триггера сборщика мусора Java RMI может управлять временем триггера, настроив -Dsun.rmi.dgc.server.gcInterval=86400.
-XX:CMSInitiatingOccupancyFraction=60: порог восстановления памяти старого поколения, значение по умолчанию — 68.
-XX:ConcGCThreads=4: строки параллельного потока сборщика мусора CMS, рекомендуемое значение — количество ядер ЦП.
-XX:ParallelGCThreads=8: Количество потоков параллельного сборщика нового поколения.
-XX:MaxTenuringThreshold=10: установить максимальный возраст мусора. Если установлено значение 0, объекты молодого поколения напрямую входят в старое поколение, не проходя через область Survivor. Для приложений с большим количеством старых поколений можно повысить эффективность. Если для этого значения установлено большее значение, объекты молодого поколения будут реплицироваться несколько раз в области Survivor, что может увеличить время выживания объектов в молодом поколении и повысить вероятность того, что они будут переработаны в молодом поколении. .
-XX:CMSFullGCsBeforeCompaction=4: после указания того, сколько раз выполняется полная сборка мусора, пространство памяти постоянной области сжимается.
-XX:CMSMaxAbortablePrecleanTime=500: когда выполнение фазы предварительной очистки abortable-preclean достигает этого времени, оно завершается.
При настройке, если вы беспокоитесь о накладных расходах на производительность, вы должны попытаться установить начальное значение и максимальное значение постоянного поколения на одно и то же значение, потому что настройка размера постоянного поколения требует достижения FullGC.
Пример оптимизации памяти
Когда JVM работает стабильно и запускается FullGC, мы обычно получаем следующую информацию:
В приведенном выше журнале gc, когда происходит fullGC, отображается использование кучи и время GC всего приложения. Чтобы быть более точным, требуется несколько коллекций, и вычисляется среднее значение. Или используйте самый длинный FullGC для оценки. На приведенном выше рисунке пространство старого поколения занимает 93168 КБ (около 93 МБ), что считается активными данными пространства старого поколения. Выделение другого пространства кучи основано на следующих правилах.
- java heap: параметры -Xms и -Xmx рекомендуется расширять в 3-4 раза больше пространства старого поколения после FullGC.
- Постоянная генерация: -XX:PermSize и -XX:MaxPermSize, после FullGc рекомендуется расширить в 1,2-1,5 раза постоянную занятость пространства.
- Новое поколение: -Xmn, после FullGC рекомендуется расширить в 1-1,5 раза место, занимаемое старым поколением.
- Старое поколение: в 2-3 раза больше пространства, занимаемого старым поколением после FullGC.
На основании вышеизложенных правил параметры определяются следующим образом:
java -Xms373m -Xmx373m -Xmn140m -XX:PermSize=5m -XX:MaxPermSize=5m
Пример оптимизации задержки
Для оптимизации задержки сначала необходимо понять требования к задержке и настраиваемые индикаторы.
- Среднее мертвое время, приемлемое для приложения: Это время связано с измеренным второстепенным значением.
- Длительность GC для сравнения. Приемлемая незначительная частота GC: незначительная
- Частота ГК сравнивается с допустимым значением.
- Максимально допустимое время паузы: максимальное время паузы сравнивается с продолжительностью FullGC в наихудшем случае.
- Максимально допустимая частота пауз: в основном частота FullGC.
Среди них среднее мертвое время и максимальное мертвое время являются наиболее важными для пользовательского опыта. Для вышеуказанных показателей соответствующий сбор данных включает в себя: продолжительность MinorGC, количество MinorGC, наихудшую продолжительность FullGC и частоту FullGC в наихудшем случае.
Как показано выше, средняя продолжительность Minor GC составляет 0,069 секунды, а частота Minor GC — один раз каждые 0,389 секунды.
Чем больше пространство нового поколения, тем дольше время GC Minor GC и тем ниже частота. Если вы хотите уменьшить его продолжительность, вам нужно уменьшить размер его пространства. Если вы хотите уменьшить его частоту, вам нужно увеличить размер его пространства.
Здесь время задержки сокращается за счет уменьшения размера пространства новой генерации на 10%. В ходе этого процесса размер старой генерации и генерации холдинга должен оставаться неизменным. Настроенные параметры изменяются следующим образом:
java -Xms359m -Xmx359m -Xmn126m -XX:PermSize=5m -XX:MaxPermSize=5m
Настройка пропускной способности
Настройка пропускной способности в основном основана на требованиях к пропускной способности приложения.Приложение должно иметь всеобъемлющий индикатор пропускной способности, который выводится на основе требований и тестирования всего приложения.
Оцените, велик ли разрыв между текущей пропускной способностью и целевым. Если он составляет около 20%, вы можете изменить параметры, увеличить память и снова выполнить отладку с нуля. Если он огромен, вам необходимо учитывать весь уровень приложения. ● Если план и цели согласованы, повторно оцените целевую пропускную способность.
Для сборщиков мусора целью настройки производительности для повышения пропускной способности является предотвращение или редкое возникновение FullGC или сжатой сборки мусора (CMS) Stop-The-World, поскольку оба метода могут снизить пропускную способность приложения. Постарайтесь переработать как можно больше объектов на этапе MinorGC, чтобы избежать слишком быстрого продвижения объектов до старости.
Инструменты настройки
С помощью инструмента анализа журнала GCViewer можно очень интуитивно проанализировать преимущества, которые необходимо настроить. Его можно проанализировать со следующих аспектов:
Память, анализировать использование памяти индикаторами Totalheap, Tenuredheap, Youngheap и др. Теоретически, чем меньше использование памяти, тем лучше;
Пауза, проанализируйте показатели по трем основным пунктам Gc pause, Fullgc pause и Total pause Теоретически, чем меньше количество GC, тем лучше, и чем короче продолжительность GC, тем лучше;
Оригинальная ссылка: "Подробная настройка производительности JVM》
Ссылка на эту статью:
(1) HTTPS://blog.CSDN.net/Computer Guoba/article/details/80176223 (2) HTTPS://Nuggets.cai/post/6844903506093015053
Серия статей "Интервьюер":
- "Подробное объяснение структуры памяти JVM》
- "Интервьюер, перестаньте спрашивать меня "Механизм сборки мусора Java GC"》
- "Интервьюер, Структура памяти Java8 JVM изменилась, постоянное преобразование в метапространство》
- "Интервьюер, перестаньте спрашивать меня "сборщик мусора Java"》
- "Загрузчик классов виртуальной машины Java и родительский механизм делегирования》
- "Подробная модель памяти Java (JMM)》
- "Подробное объяснение принципов модели памяти Java.》
- "Подробная настройка производительности JVM》