Большой опыт настройки JVM для трансграничной электронной коммерции

Java JVM сервер CMS



помещение:
Крупномасштабный трансграничный бизнес электронной коммерции развивается очень быстро, и онлайн-машины часто расширяются, однако для работы онлайн-машин, особенно памяти JVM, никогда не существовало единого стандарта для владельцев каждого приложения. услуга. После повышения 618 я обсуждал с одноклассниками по эксплуатации и обслуживанию, надеясь стандартизировать параметры jvm онлайн-сервера, которые можно унифицировать для каждого приложения, повысить стабильность онлайн-сервера и уменьшить потребность в всем настраивать.время параметра jvm.
Ссылаясь на опыт компании, которая раньше работала в Taobao Tmall: После обсуждения, в соответствии с версией jdk и конфигурацией онлайн-машины, был определен рекомендуемый шаблон jvm по умолчанию:

Окончательный рекомендуемый шаблон jvm:
версия jdk конфигурация машины рекомендуемые параметры jvm примечания
jdk1.7 6V8G -server -Xms4g -Xmx4g -Xmn2g -Xss768k -XX:PermSize=512m -XX:MaxPermSize=512m -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSClassUnloadingEnabled -XX:+DisableExplicit -XX:+ UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=68 -verbose:gc -XX:+PrintGCDetails -Xloggc:{CATALINA_BASE}/logs/gc.log -XX:+PrintGCDateStamps -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath={CATALINA_BASE}/logs
jdk1.7 8V8G -server -Xms4g -Xmx4g -Xmn2g -Xss768k -XX:PermSize=512m -XX:MaxPermSize=512m -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSClassUnloadingEnabled -XX:+DisableExplicit -XX:+ UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=68 -verbose:gc -XX:+PrintGCDetails -Xloggc:{CATALINA_BASE}/logs/gc.log -XX:+PrintGCDateStamps -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath={CATALINA_BASE}/logs
jdk1.7 4V8G -server -Xms4g -Xmx4g -Xmn2g -Xss768k -XX:PermSize=512m -XX:MaxPermSize=512m -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSClassUnloadingEnabled -XX:+DisableExplicit -XX:+ UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=68 -verbose:gc -XX:+PrintGCDetails -Xloggc:{CATALINA_BASE}/logs/gc.log -XX:+PrintGCDateStamps -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath={CATALINA_BASE}/logs
jdk1.7 6V8G -server -Xms4g -Xmx4g -XX:MaxPermSize=512m \
-verbose:gc -XX:+PrintGCDetails -Xloggc{CATALINA_BASE}/logs/gc.log -XX:+PrintGCTimeStamps \ backend


Рекомендуемая конфигурация для интернет (bat) компании:




Инструкции по настройке:
1. Настройки кучи
o -Xms: начальный размер кучи
o -Xmx: максимальный размер кучи
o -XX:NewSize=n: установить размер молодого поколения
o -XX:NewRatio=n: установить соотношение молодого поколения к старому. Например, это 3, что означает, что соотношение молодого поколения к старому составляет 1:3, а молодое поколение составляет 1/4 от суммы молодого поколения и старого поколения.
o -XX:SurvivorRatio=n: отношение площади Эдема к двум областям выживших в молодом поколении. Обратите внимание, что в области выживших их два. Например: 3 означает Эдем: Выживший=3:2, область Выживших занимает 1/5 всего молодого поколения.
o -XX:MaxPermSize=n: установить постоянный размер генерации
2. Настройки коллектора
o -XX:+UseSerialGC: установить серийный сборщик
o -XX:+UseParallelGC: установить параллельный сборщик
o -XX:+UseParalledlOldGC: установить параллельный сборщик старого поколения
o -XX:+UseConcMarkSweepGC: установить параллельный сборщик
3. Статистика сбора мусора
-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-Xloggc:filename
"
4. Настройки параллельного коллектора
-XX:ParallelGCThreads=n: установить количество процессоров, используемых параллельным сборщиком для сбора. Количество параллельных потоков сбора.
-XX:MaxGCPauseMillis=n: установить максимальное время паузы для параллельного сбора
-XX:GCTimeRatio=n: установить процентное соотношение времени сборки мусора к времени выполнения программы. Формула 1/(1+n)
5. Настройки параллельного коллектора
-XX:+CMSIncrementalMode: установить инкрементный режим. Подходит для ситуации с одним процессором.
-XX:ParallelGCThreads=n: установить количество ЦП, используемых, когда режим сбора данных молодого поколения параллельного сборщика — параллельный сбор. Количество параллельных потоков сбора.
(4)

Объяснение параметра:

-Xms3072m -Xmx3072m
Для настроек кучи JVM минимальное и максимальное значения ограничены -Xms -Xmx
-Xmn1024m устанавливает размер молодого поколения на 1024м
Полный размер памяти JVM = размер молодого поколения + размер старого поколения + постоянный размер поколения (perm).

-Xss768k Устанавливает размер стека для каждого потока. После JDK5.0 размер стека каждого потока составляет 1 МБ, а предыдущий размер стека каждого потока — 256 КБ. Отрегулируйте размер памяти, требуемый потоками приложения. В той же физической памяти уменьшение этого значения может создать больше потоков. Однако операционная система по-прежнему имеет ограничение на количество потоков в процессе, которое не может генерироваться бесконечно, а значение опыта составляет около 3000–5000.

-XX:PermSize=512m -XX:MaxPermSize=512m
Постоянное поколение обычно фиксируется на уровне 64 м, поэтому после увеличения молодого поколения размер старого поколения будет уменьшен. Это значение сильно влияет на производительность системы, и Sun официально рекомендует устанавливать его равным 3/8 всей кучи.
Установите начальное значение не кучи памяти, по умолчанию 1/64 физической памяти; установите максимальный размер не кучи памяти XX:MaxPermSize, по умолчанию 1/4 физической памяти

-XX:+UseConcMarkSweepGC
Сборщик CMS также известен как параллельный сборщик с короткой паузой. Это мусор, собранный на старом поколении. Сборщик CMS выполняет сборку мусора одновременно через несколько потоков, чтобы свести к минимуму паузы, вызванные сборкой мусора. Сборщик CMS использует тот же алгоритм для сборки мусора молодого поколения, что и сборщик Parallel. Этот сборщик мусора подходит для приложений, не терпящих длительных пауз и требующих быстрых ответов.

-XX:+UseParNewGC использует многопоточный параллельный сбор для молодого поколения, поэтому сбор выполняется быстрее;

-XX:+CMSClassUnloadingEnabled
Если вы включите CMSClassUnloadingEnabled, сборка мусора очистит постоянное поколение, удалив классы, которые больше не используются. Этот параметр полезен, только если UseConcMarkSweepGC также включен.

-XX:+DisableExplicitGC запрещает System.gc(), чтобы программист по ошибке не вызвал метод gc и не повлиял на производительность;

-XX:+UseCMSInitiatingOccupancyOnly
Флаг, указывающий JVM не инициировать цикл сборки мусора CMS на основе данных, собранных во время выполнения. Вместо этого, когда этот флаг установлен, JVM выполняет каждую CMS-коллекцию через значение CMSInitiatingOccupancyFraction, а не только в первый раз. Однако имейте в виду, что в большинстве случаев JVM может принимать лучшие решения по сборке мусора, чем мы. Поэтому этот флаг следует использовать только тогда, когда у нас есть веская причина (например, тестирование) и глубокое понимание жизненного цикла объектов, создаваемых приложением.

-XX:CMSInitiatingOccupancyFraction=68
CMS по умолчанию запускает сбор CMS, когда на постоянное поколение (старое поколение) приходится 68%.Если ваше старое поколение не растет так быстро и вы хотите уменьшить количество CMS, вы можете соответствующим образом увеличить это значение;

-XX:+UseParNewGC: Использовать многопоточную параллельную переработку для молодого поколения, чтобы сбор был быстрее;


-XX:HeapDumpPath
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-Xloggc:/usr/aaa/dump/heap_trace.txt
Приведенные выше параметры воспроизводят информацию о дампе кучи.

" -XX:+HeapDumpOnOutOfMemoryError
Этот параметр может управлять информацией о куче при печати OutOfMemoryError.


Возможно, вы заметили, что здесь для сборки мусора рекомендуется использовать метод cms;
CMS — это сборщик, целью которого является получение кратчайшего времени паузы восстановления, что может эффективно сократить время паузы сервера;
Поток GC CMS будет занимать относительно высокий коэффициент использования ЦП, но он по-прежнему демонстрирует превосходные характеристики на многоядерных серверах и в настоящее время развернут на основных отечественных веб-сайтах электронной коммерции. Так что это очень рекомендуется здесь!

Понятие смс:
Сборщик CMS также известен как параллельный сборщик с короткой паузой. Это мусор, собранный на старом поколении. Сборщик CMS выполняет сборку мусора одновременно через несколько потоков, чтобы свести к минимуму паузы, вызванные сборкой мусора. Сборщик CMS использует тот же алгоритм для сборки мусора молодого поколения, что и сборщик Parallel. Этот сборщик мусора подходит для приложений, не терпящих длительных пауз и требующих быстрых ответов. CMS использует множество методов для минимизации времени паузы GC и уменьшения паузы пользовательской программы. Время паузы сокращается при снижении пропускной способности процессора. Это компромисс между временем паузы и производительностью, которую можно просто понимать как «пространство (производительность)» для времени.

Скорректированный ритм:
Из-за боязни повлиять на онлайн-приложение этапы настройки разделены на три шага:
Шаг 1: Частично воздействовать на небольшое количество пилотов машин, сравнивать ненастроенные машины и наблюдать за скорректированными результатами;
Шаг 2: Настройте параметры некоторых приложений, выполните стресс-тестирование и наблюдайте за эффектом после интенсивного одновременного стресс-тестирования;
Третий шаг: настроить параметры jvm некоторых основных приложений и фактически проверить эффект через продвижение 818;
На данный момент акция 818 завершена. Лишь бы подвести итоги.

Один: долгосрочная производительность,
Первое изменение: уменьшено количество фгк, которое сократилось более чем в два раза;
Для мобильного проекта в основном 1-2 машины в день до корректировки и в основном каждые 2-3 дня после корректировки:



онлайн (другой проект): Хорошо видно, что статистическая частота фгк значительно меньше;





Второе изменение: уменьшено время fgc








Раньше для fgc требовалось почти 500 мс, но теперь это занимает менее 100 мс.
Это также доказывает, что самым большим преимуществом cms является сокращение времени паузы fgc.

Второе: стресс-тестирование и высокая эффективность продвижения.
Время fgc в основном значительно сокращается, время yanggc больше, а количество раз сильно не меняется;
Источник данных: сводка стресс-тестов команды тестировщиков.

xxxx-online4.server.org
CMS

xxxx-online1.server.org
CMS

xxxx-online34.server.org
сборщик мусора по умолчанию

инструкция

полный gc раз

1

1

1

общее время fullgc

343

250

1219

Время сборщика мусора/CMS fullgc по умолчанию

3.55

4.88

CMS fullgcВремя значительно меньше, чем время сборщика мусора по умолчанию..

момент времени fullgc

2:48:36

3:14:36

5:30:36

Использование CPU% во время fullgc

40%

10%

16%

средняя нагрузка при полной загрузке

1.19

0.49

1.21

Общее количество молодых gc

1094

1098

1078

общее время

44093

44632

30387

среднее время

40.30

40.65

28.19

максимальное время

1332

1268

928

CMS/сборщик мусора по умолчанию (общее время Younggc)

1.45

1.47

Время CMS younggc больше, чем сборщик мусора по умолчанию

CMS/сборщик мусора по умолчанию (среднее время Younggc)

1.43

1.44

Время CMS younggc больше, чем сборщик мусора по умолчанию

CMS/сборщик мусора по умолчанию (максимальное время для Younggc)

1.44

1.37

Время CMS younggc хуже, чем сборщик мусора по умолчанию в худшем случае

<!--EndFragment-->

Три: Объяснение того, сколько раз полный gc подсчитывается на дозорном, на дозорном
Мы можем смело сказать:
1. Полный GC == Major GC относится к остановке мирового GC для старого/постоянного поколения
2. Количество Полных GC = количество раз остановки мира во время GC старого поколения
3. Полное время GC = общее время, чтобы остановить мир во время старости GC
4. CMS не равно Full GC.Мы видим, что CMS разделен на несколько этапов.Только этап остановки мира рассчитывается на количество и время полного GC, а количество и время GC одновременно с бизнес-потоками не считается. Полный GC

Количество полных общих сборок относится к количеству остановок мира, поэтому CMS увеличит количество полных общих сборок как минимум на 2, потому что и начальная отметка CMS, и примечание остановят мир, что записывается как 2 раза. И CMS может выйти из строя и снова вызвать полный сборщик мусора
Если во время параллельного процесса сборки CMS происходит сбой параллельного режима, то затем будет выполняться полная сборка мусора с маркировкой-очисткой-компактом, что полностью остановит мир.

Именно благодаря этой функции счетчик полного GC обновляется дважды в каждом параллельном цикле GC CMS, начальная метка и окончательная повторная маркировка каждый раз; если происходит сбой в параллельном режиме, следующий полный GC будет подсчитываться один раз.

Четыре: Возникло несколько проблем:
Вопрос 1: переполнение стека;
Параметр -Xss256k был скорректирован, и отзыв от Юантао может повлиять на вызов трассировки. Сообщите о следующей ошибке:
Java.lang.StackOverflowError
at net.sf.jsqlparser.util.deparser.ExpressionDeParser.visitBinaryExpression(ExpressionDeParser.java:278)
at net.sf.jsqlparser.util.deparser.ExpressionDeParser.visit(ExpressionDeParser.java:246)
at net.sf.jsqlparser.expression.operators.conditional.OrExpression.accept(OrExpression.java:37)
at net.sf.jsqlparser.util.deparser.ExpressionDeParser.visitBinaryExpression(ExpressionDeParser.java:278)
at net.sf.jsqlparser.util.deparser.ExpressionDeParser.visit(ExpressionDeParser.java:246)
Потому что этот параметр должен установить размер стека каждого потока. После JDK5.0 размер стека каждого потока составляет 1 МБ, а предыдущий размер стека каждого потока — 256 КБ. В той же физической памяти уменьшение этого значения может создать больше потоков.
Итак, сегодня удалите параметр -Xss256k машины инвентаризации, чтобы увидеть, не является ли это причиной.

Проблема 2: Фаза маркировки инициализации занимает слишком много времени:
Общая рекомендация заключается в том, что время двух STW на этапе cms не превышает 200 мс.Если время, вызванное этапом начальной отметки CMS, слишком велико:
На начальном этапе маркировки (начальная маркировка CMS), чтобы минимизировать временные затраты STW, мы можем использовать:
-XX:+CMSParallelInitialMarkEnabled
Обеспечить распараллеливание в процессе начальной маркировки для дальнейшего повышения эффективности начальной маркировки;
Проблема 3: время ожидания на стадии замечания слишком велико
Как показано ниже:




Возможные способы:
Запустите ygc один раз перед CMS GC, цель состоит в том, чтобы уменьшить ссылку старого поколения на ygc gen и уменьшить накладные расходы на перемаркировку ----- 80% времени GC в целом CMS находится на стадии примечания.
-XX:+CMSScavengeBeforeRemark
jmap-анализ:




Вопрос 4: Ошибка OutOfMemoryError, вызванная тем, что инфраструктура nio занимает DirectMemory
Метод обработки: используйте XX:+DisableExplicitGC
Увеличьте размер DirectMemory;
1. DirectMemory не относится к динамической памяти java.Выделение памяти фактически вызывает функцию Os:malloc() операционной системы.
2. Емкость может быть указана с помощью -XX:MaxDirectMemorySize.Если она не указана, значение по умолчанию совпадает с максимальным значением кучи Java (указывается с помощью -Xmx). Обратите внимание, что прямая память по умолчанию для ibm jvm не имеет прямого отношения к -Xmx.
3. Использование памяти Direct Memory позволяет избежать копирования данных между кучей Java и собственной кучей. Повышение производительности в определенных сценариях.
4. Объекты Direct ByteBuffer автоматически очищают собственные буферы, но этот процесс может выполняться только как часть сборщика мусора кучи Java, поэтому они не реагируют автоматически на давление, оказываемое на собственную кучу.
5. GC происходит только тогда, когда куча Java настолько заполнена, что не может обслуживать запросы на выделение кучи, или когда приложение Java явно вызывает функцию System.gc() для освобождения памяти (некоторые платформы NIO используют этот метод для освобождения занятой памяти DirectMemory). .
6. Неразумное использование этой области также вызовет OutOfMemoryError.
7. В случае, когда Buffer необходимо создавать часто, использование DirectBuffer нецелесообразно из-за высокой стоимости создания и уничтожения DirectBuffer.Однако, если DirectBuffer можно использовать повторно, то в случае частого чтения и записи он может быть значительно улучшена производительность. (Чтение и запись в DirectBuffer быстрее, чем в обычный Buffer, но его создание и уничтожение медленнее, чем в обычный Buffer).