Привет всем, я Сяо Цай, Сяо Цай, который хочет быть Цай Буцаем в интернет-индустрии. Она может быть мягкой или жесткой, как она мягкая, а белая проституция жесткая!
Черт~ Не забудьте поставить мне тройку после прочтения!
"Эта статья в основном знакомит
JVM和GC解析
При необходимости вы можете обратиться к
Если это поможет, не забудьтеподобно❥Творить нелегко, проституция бессмысленна!
1. Понимание ООМ
StackOverflowError
public static void main(String[] args) {
stackOverflowError(); //Exception in thread "main" java.lang.StackOverflowError
}
private static void stackOverflowError() {
stackOverflowError();
}
OutOfMemeoryError: пространство кучи java
public static void main(String[] args) {
String str = "cbuc";
for (; ; ) {
str += str + UUID.randomUUID().toString().substring(0,5); //+= 不断创建对象
}
}
OutOfMemeoryError: превышен лимит накладных расходов GC
Программа тратит 98% своего времени на сборку мусора, но не собирает 2% места.
если не броситьGC overhead limit
, вызовет:
- Небольшая часть памяти, очищенная сборщиком мусора, вскоре снова заполнится, заставив сборщик мусора выполниться снова, создав тем самым порочный круг.
- Использование CPU всегда на 100%, а GC ничего не делает
OutofMeMeoryError: Прямая буферная память
- Написание программ NIO часто используется
ByteBuffer
для чтения или записи данных, которые основаны на канале(Channel)
и буфер(Buffer)
режим ввода-вывода, он может использоватьNative
Куча, выделенная библиотекой из внешней памяти, затем куча сохраняется в Java с помощьюDirectByteBuffer
Объекты действуют как ссылки на эту часть памяти. Это может значительно повысить производительность в некоторых сценариях, посколькуИзбегайте копирования данных туда и обратно между кучей Java и собственной кучей.
ByteBuffer.allocate(capability)
: Этот метод заключается в выделении памяти кучи JVM, которая находится под юрисдикцией GC, и является относительно медленным из-за необходимости копирования.
ByteBuffer.allocateDirect(capability):
Этот метод заключается в выделении локальной памяти ОС, которая не находится под юрисдикцией GC, поскольку он не требует копирования памяти и является относительно быстрым.
Но если локальная память выделяется постоянно, а память кучи используется редко, то JVM не нужно выполнятьGC
,DirectByteBuffer
Объект не будет переработан. На данный момент памяти кучи достаточно, но локальная память могла быть израсходована. Попробуйте еще раз выделить локальную память.OutOfMemeoryError
, программа сразу вылетает.
public static void main(String[] args) {
/**
* 虚拟机配置参数
* -Xms10m -Xmx10m -XX:+PrintGCDetails -XX:MaxDirectMemorySize=5m
*/
System.out.println("配置的maxDirectMemeory:"+ (sun.misc.VM.maxDirectMemory()/(double)1024/1024)+"MB");
try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}
// -XX:MaxDerectMemorySize=5m 配置为5m, 这个时候我们使用6m
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(6*1024*1024);
}
OutOfMemeoryError:unable to create new native thread
Это исключение часто возникает, когда к серверу поступает много одновременных запросов.
причина:
- Ваше приложение создало слишком много потоков, и один процесс приложения создает несколько потоков, что превышает разрешение системы.
- Ваш сервер не позволяет вашему приложению создавать так много потоков,
linux
Количество потоков, которые может создать процесс, разрешенное системой по умолчанию.1024
Если ваше приложение создает больше, чем это число, об этом будет сообщеноOutOfMemeoryError:unable to create new native thread
Решение:
- Найдите способы уменьшить количество потоков, создаваемых вашим приложением, проанализируйте, действительно ли приложению нужно создавать такое количество потоков, и если нет, измените код, чтобы свести к минимуму количество потоков.
- Для небольшого приложения нужно создать много потоков, гораздо больше, чем
linux
системные установки по умолчанию1024
Лимит потоков может быть изменен с помощьюlinux
Конфигурация сервера, развернутьlinux
ограничение по умолчанию
public static void main(String[] args) {
for (int i = 1; ; i++) {
System.out.println("输出 i: " + i);
new Thread(()->{
try {TimeUnit.SECONDS.sleep(Integer.MAX_VALUE);} catch (InterruptedException e) {e.printStackTrace();}
},"线程"+i).start();
}
}
OutOfMemeoryError: Метапространство
Java 8 и более поздние версии используют Metaspace вместо постоянного поколенияMetaspace
это область метода вHotSpot
Самая большая разница между ним и постоянной полосой заключается в том, что:Metespace
Не в памяти виртуальной машины, а с использованием локальной памяти
Постоянное поколение (замененное исходным пространством Metaspace после java8) хранит следующую информацию:
- Информация о классе, загружаемая виртуальной машиной
- постоянный пул
- статическая постоянная
- Своевременно скомпилированный код
2. 4 вида сборщиков мусора
Алгоритм GC (подсчет ссылок/копирование/стандартное разрешение/стандартное целочисленное значение)метод восстановления памяти,Сборщик мусора — это реализация алгоритма
Пока нет идеального коллектора, нет универсального коллектора, есть только наиболее подходящий коллектор для конкретных задач.Коллекция поколений
Серийный сборщик мусора (Serial)
Он разработан для однопоточной среды и использует только один поток для сборки мусора, приостанавливая все пользовательские потоки. Так что не подходит для серверной среды.
Параллельный сборщик мусора (параллельно)
Несколько потоков сборки мусора работают параллельно, а пользовательский поток в это время приостанавливается, что подходит для сценариев слабого взаимодействия, таких как научные вычисления/обработка больших данных.
Параллельный сборщик мусора (CMS)
Пользовательский поток и поток сборки мусора выполняются одновременно (не обязательно параллельно, но могут выполняться попеременно), и пользовательский поток не нужно ставить на паузу, что подходит для сценариев, требующих времени отклика
Сборщик мусора G1
Сборщик мусора G1 делит память кучи на разные регионы, и мусор собирает их одновременно.
Три, анализ сборщика мусора
Просмотр сборщика мусора по умолчанию
java -XX:+PrintCommandLineFlags -version
сборщик мусора по умолчанию
UseSerialGC
UseParallelGC
UseConcMarkSweepGC
UseParNewGC
UseParallelOldGC
UseG1GC
Кайнозой
-
Серийный GC (серийный) / (серийный колпачок)
Однопоточный сборщик во время сборки мусора должен приостановить все остальные рабочие потоки, пока не закончит сбор
Самый стабильный и эффективный сборщик использует только один поток для сборки, но может вызывать длительные паузы (состояние «Stop-The-World») во время сборки мусора. Хотя все другие рабочие потоки должны быть приостановлены во время процесса сборки мусора, он прост и эффективен.Для ограниченной среды с одним процессором == никакие накладные расходы на взаимодействие потоков не могут обеспечить более высокую эффективность однопоточной сборки мусора, == Следовательно, последовательный мусор Collector по-прежнему является сборщиком мусора нового поколения по умолчанию для виртуальной машины Java, работающей в клиентском режиме.
Параметры настройки JVM:-XX:+UseSerialGC
После открытия он будет использовать:Serial(Young区用)+Serial Old(Old区用的)收集器组合
,
выражать:
И новое поколение, и старое поколение используют последовательные сборщики коллекций, новое поколение использует алгоритм репликации, а старое поколение использует алгоритм сортировки по меткам.
- Параллельный сборщик мусора (ParNew)
Используйте многопоточность для сборки мусора.Во время сборки мусора Stop-The-World приостанавливает все остальные рабочие потоки, пока не закончит сбор
ParNew
Коллектор на самом деле представляет собой новое поколение коллекционера Serial.Параллельная многопоточная версия, самый распространенный сценарий применения - с пожилым возрастомCMS GC
работает, в остальном поведение точно такое же, как у серийного сборщика,ParNew
Сборщик мусора также приостанавливает все рабочие потоки во время сборки мусора.Это сборщик мусора по умолчанию для нового поколения многих виртуальных машин Java, работающих в режиме сервера.
Параметры настройки JVM:
XX:+UseParNewGC
Включение сборщика ParNew влияет только на коллекцию молодого поколения, а не на старое поколение. После включения вышеуказанных параметров он будет использовать:ParNew (新生代区用)+Serial Old(老年代区用)策略
,Новое поколение использует алгоритм копирования, а старое поколение использует алгоритм маркировки-сопоставления..
-
Параллельная переработка GC (Parallel) / (Parallel Scavenge)
Parallel Scavenge
коллекционер какParNew
СлишкомСборщик мусора молодого поколения,использоватькопироватьалгоритм тожепараллельная многопоточностьСборщик мусора, широко известный как сборщик первой пропускной способности.Распараллеливание последовательных коллекторов в молодом и старом поколениях关注点:
контролируемая пропускная способность
-
Стратегия адаптивной корректировки также является важным отличием сборщика ParallelScavenge от сборщика ParallelNew.
Параметры настройки JVM
-XX:UseParallelGC
или-XX:UseParallelOldGC
(можно активировать друг друга), после открытия:Новое поколение использует алгоритм копирования, а старое поколение использует алгоритм маркировки-сопоставления..
старость
-
Серийный GC (серийный старый) / (серийный MSC)
Serial Old — старая версия сборщика мусора Serial., который также является однопоточным сборщиком, использующимОтметить-организоватьАлгоритм, этот сборщик также в основном работает на сборщике мусора старого поколения по умолчанию на виртуальной машине Java клиента по умолчанию.
использовать:
- В версиях до JDK 1.5 и нового поколения
Parallel Scavenge
Использование с коллекторами. (Parallel Scavenge+Serial Old
) - В качестве запасной схемы сборки мусора с использованием сборщика CMS в старых версиях.
-
Параллельный GC (параллельный старый) / (параллельный MSC)
Parallel Old
коллекционерParallel Scavenge
старая версия,использоватьМногопоточная организация разметкиАлгоритм Parallel Старый до JDK 1.6, новое поколение используетParallelScavenge
Коллектор может гарантировать только пропускную способность нового поколения, но не может гарантировать общую пропускную способность. До JDK1.6 (Parallel Scavenge+Serial Old
)Parallel Old
Именно для обеспечения сборщика мусора с приоритетом пропускной способности в старом поколении.Если система имеет высокие требования к пропускной способности,После JDK1.8 можно отдать приоритет новому поколениюParallel Scavenge
и старое поколениеParallel Old
Стратегия коллокации сборщика.Параметры настройки JVM:
-XX:+UseParallelOldGC
Откройте сборщик Parallel Old, после установки этого параметра используйте新生代Parallel + 老年代Parallel Old
Стратегия -
Concurrent Mark Sweep GC (CMS)
преимущество:
Параллельный сбор с небольшими паузами
недостаток: 并发执行,对CPU资源压力大
:
Из-за параллелизма CMS будет увеличивать занятость кучи памяти одновременно при сборе и применении потоков, то естьCMS должен завершить сборку мусора до того, как память кучи старого поколения будет исчерпана, иначе при сбое сборки CMS, сработает гарантийный механизм, и старый серийный коллектор выполнит сборку мусора в режиме STW, что приведет к большой паузе.-
采用的标记清除算法会导致大量碎片
:
Алгоритм mark-and-sweep не может отсортировать фрагменты пространства, и пространство старого поколения будет постепенно исчерпано временем приложения, и тогда память кучи придется сжимать через гарантийный механизм. CMS также предоставляет параметры-XX:CMSFulllGCsBeForeCompaction
(По умолчанию — 0, т. е. сортировка памяти выполняется каждый раз), чтобы указать, сколько коллекций CMS необходимо выполнить сжатой полной сборкой мусора.4 ключевых шага:
Initial Mark (初始标记)
: Прямой доступ к объекту тега GC Root, занимает мало времени.Concurrent Mark(并行标记)
: Начиная с объекта, отмеченного на первом этапе, достижимые объекты отмечаются одновременно.Remark(重新标记)
: перемаркировать, исправить изменения между объектами и вновь созданными объектами, вызванные запуском пользовательской программы во время параллельной маркировки, что занимает меньше времени.-
Concurrent Sweep(并行回收)
: Сборка мусора выполняется параллельно.
Как выбрать сборщик мусора
- Один ЦП или небольшая память, автономная программа
-XX:+UseSerialGC
- Несколько ЦП, требующих максимальной пропускной способности, например приложения для фоновых вычислений.
-XX:+UseParallelGC
-XX:+UseParallelOldGC
- Несколько процессоров, стремление к малому времени паузы, быстрый отклик, например, интернет-приложения
-XX:+UseConcMarkSweepGC
-XX:+ParNewGC
В-четвертых, сборщик мусора G1
Особенности предыдущих сборщиков мусора:
- Молодое и старое поколения представляют собой отдельные и непрерывные блоки памяти.
- В молодом поколении Eden+S0+S1 использует алгоритм репликации для сбора
- Коллекция старого поколения должна сканировать всю область старого поколения
- Оба предназначены для выполнения GC как можно меньше и быстрее
Концепция G1:
Garbage-First
Сборщик является сборщиком для серверных приложений.Преимущества заключаются в следующем:
- Организуйте свободное пространство быстрее
- Нужно больше времени, чтобы предсказать время паузы GC
- Не хотите жертвовать большой пропускной способностью
- Нет необходимости в большой Java-куче
Коллектор G1 предназначен для замены коллектора CMS.
Преимущества G1:
- G1 — это сборщик мусора с процессом сортировки памяти, который не приводит к сильной фрагментации памяти.
- G1
Stop-The-World (STW)
Более управляемый, G1 добавлен во время паузымеханизм предсказания, пользователь может указать желаемое время паузы
Основное изменениеEden
,Survivor
а такжеTenured
Когда область памяти больше не является непрерывной, она становится одинакового размера одна за другой.region
, каждыйregion
от1M
прибыть32M
не ждать. Одинregion
скорее всего принадлежитEden
,Survivor
илиTenured
область памяти.
Особенности G1:
- G1 может в полной мере использовать многопроцессорные, многоядерные аппаратные преимущества среды, попытаться сократить
STW
- G1 в целом принимаетОтметить-организоватьалгоритм, локально путем копирования алгоритма,отсутствие фрагментации памяти
- С макроэкономической точки зрения молодое поколение и старое поколение больше не различаются в G1.Разделить память на несколько независимых субрегионов (Region)
- В коллекторе G1 смешана вся область памяти,Но все же необходимо различать молодое поколение и старое поколение в небольшом диапазоне., которая сохраняет молодое и старое поколения.
- Хотя G1 также является сборщиком поколений, весь раздел памятине существует физическиРазница между молодым поколением и старым поколением не требует полностью независимой оставшейся (в космос) кучи для подготовки к репликации. G1только логическая концепция поколения, или что каждый раздел может переключаться между разными поколениями во время работы G1.
Основной принцип G1
"(1) Региональный сборщик мусора ·
Регионализованная область нарезки памяти в целом компилируется в ряд прерывистых областей памяти, что позволяет избежать операции GC всей области памяти.
Главная мысль:
Разделите всю область динамической памяти на подобласти одинакового размера (Region
), когда запускается JVMАвтоматически настраивать размер этих субрегионов.
При использовании кучиG1 не требует хранения объектов, которые должны быть физически смежными, если они логически непрерывны., каждый раздел не будет постоянно обслуживать определенное поколение и может переключаться между молодым поколением и старым поколением по мере необходимости. При запуске можно передать параметры-XX:G1HeapRegionSize=n
Вы можете указать размер раздела (1MB~32MB
, и должна быть степенью 2), по умолчанию вся куча делится на2048
перегородки.
размерный ряд в1MB~32MB
, вы можете настроить2048
Регион, то есть максимальная поддерживаемая память:32MB*2048=65536MV=64G
ОЗУ
Самое большое преимущество состоит в том, чтобы разделить все на ноль, избежать полного сканирования памяти и сканировать нужно только в соответствии с регионом.
"(2) Этап восстановления
Сбор для области Эдема будет запущен, когда область Эдема будет исчерпана, в основном сбор небольших областей + формирование непрерывных блоков памяти, чтобы избежать фрагментации памяти.
-
Eden
данные области перемещаются в новуюSurvivor
область, некоторые данные продвигаются вOld
Площадь. -
Survivor
данные области перемещаются в новуюSurvivor
область, некоторые данные продвигаются вOld
Площадь. - Наконец, область Eden очищается, GC завершается, и пользовательское приложение продолжает выполняться.
"(3) Выполните четыре шага
-
начальная отметка:
отмечать только
GC Roots
объекты, которые могут быть непосредственно связаны с -
одновременная маркировка:
провести
GC Roots Tracing
процесс -
окончательная оценка:
Зафиксировать часть объекта, маркировка которого изменяется из-за выполнения программы при параллельной маркировке
-
Проверка на переработку:
Максимальное восстановление стоимости в зависимости от времени
"(4) Общие параметры конфигурации
-
-XX:+UseG1GC
Включите сборщик мусора G1 -
-XX:G1HeapRegionSize=n
Устанавливает размер области G1. Значения являются степенью двойки и варьируются от 1M до 32M. Цель состоит в том, чтобы выделить около 2048 регионов на основе наименьшего размера кучи Java. -
-XX:MaxGCPauseMillis=n
Максимальное время паузы, это мягкая цель, JVM попытается (но не гарантирует) время паузы меньше этого времени -
-XX:InitiatingHeapOccupancyPercent=n
GC срабатывает, когда куча занята, по умолчанию 45. -
-XX:ConcGCThreads=n
Количество потоков, используемых параллельным сборщиком мусора -
-XX:G1ReservePercent=n
Установите процент зарезервированной памяти как время простоя, чтобы снизить риск переполнения целевого пространства, значение по умолчанию — 10%.
"(5) Преимущества по сравнению с CMS
- G1 не вызывает фрагментацию памяти
- Пауза может точно контролироваться.Сборщик делит всю кучу (новое поколение, старое поколение) на несколько областей фиксированного размера и каждый раз собирает наибольшую область мусора в соответствии с разрешенным временем паузы.
"(6) Сводка
5. Диагностика замедления работы сервера производственной среды.
Связанные с машиной
top
Первые пять строк — статистика
Первая строка — это информация об очереди задач, которая совпадает с результатом выполнения команды uptime.
17:16:47:
Текущее времяup 23:47:
время безотказной работы системы2 users:
Количество зарегистрированных в настоящее время пользователейload average:0.21,0.27,0.19:
Загрузка системы, средняя длина очереди для обеих задач, три значения были на 1 минуту, 5 минут, 15 минут раньше текущего среднего
связанные с процессором
1)vmstat
vmstat -n 2 3
Первый параметр — это количество временных интервалов выборки (единица измерения: секунды), а второй параметр — количество периодов выборки.
Основные параметры:
-
procs
день:Количество запущенных процессов и ожидающих квантов времени ЦП.В принципе, очередь выполнения ЦП с одним ядром не должна превышать 2, а очередь выполнения всей системы не должна превышать 2-кратного общего числа ядер.В противном случае, давление в системе будет слишком высоким.
Не делайте:Количество процессов, ожидающих ресурсов, таких как ожидание дискового ввода-вывода, сетевого ввода-вывода и т. д. -
cpu
нас:Процент процессорного времени, потребляемого пользовательскими процессами. Если значение us высокое, пользовательский процесс потребляет больше процессорного времени. Если больше 50% в течение длительного времени, программа нуждается в оптимизации.
сы:Процент процессорного времени, потребляемого процессами ядра
Эталонное значение us + sy равно 80. Если us + sy больше 80%, это означает, что ЦП может не хватать.
я бы:процент простоя процессора
ж:Процент процессорного времени, которое система тратит на ожидание ввода-вывода.
сы:Процент процессорного времени, украденного у виртуальной машины
2)mpstat
mpstat -P ALL 2
Просмотр информации о ядре ЦП
3)pidstat
pidstat -u 1 -p 进程号
Разбивка информации об использовании ЦП каждым процессом
связанные с памятью
free
Доступная память в физической памяти приложения/системы > 70%:内存充足
Доступная память приложения/системная физическая память :需要增加内存
20% :内存基本够用
Связанный с жестким диском
df
Проверить количество оставшихся свободных дисков
Жесткий диск, связанный с вводом/выводом
iostat -xdk 2 3
Шестой, анализировать производственные среды высокий процессор CPU
шаг 1
Сначала сtop
Команда, чтобы узнать максимальную загрузку ЦП
Шаг 2
ps -ef
илиjps
Дальнейшее позиционирование, знать, что это за фоновая программа
Шаг 3
Найдите конкретный поток или кодps -mp 进程 ==-o== THREAD,tid,time
-o
: этот параметр является определяемым пользователем форматом.-p
: время, когда процесс pid использует процессор-m
: показать все темы
Шаг 4
Преобразование требуемого идентификатора потока в шестнадцатеричный формат (строчный английский формат)
повторное использование:printf "%x/\n" 有问题的线程ID
Шаг 5:
jstat 进程ID | grep tid(16进制线程ID小写英文)
Семь часто используемых инструментов мониторинга и анализа производительности JVM.
-
jps
Инструмент состояния процесса виртуальной машины
-
jinfo
Инструмент информации о конфигурации Java
-
jmap
инструмент отображения памяти
-
jstat
Инструмент мониторинга статистики
"Если вы будете усердно работать сегодня, завтра вы сможете сказать на одну вещь меньше, чтобы попросить о помощи!
Я Сяо Цай, человек, который учится у вас.
💋