Разъясните JVM и GC в одной статье (ниже)

Java
Разъясните JVM и GC в одной статье (ниже)

Привет всем, я Сяо Цай, Сяо Цай, который хочет быть Цай Буцаем в интернет-индустрии. Она может быть мягкой или жесткой, как она мягкая, а белая проституция жесткая!
Черт~ Не забудьте поставить мне тройку после прочтения!

"

Эта статья в основном знакомит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

Это исключение часто возникает, когда к серверу поступает много одновременных запросов.
причина:

  1. Ваше приложение создало слишком много потоков, и один процесс приложения создает несколько потоков, что превышает разрешение системы.
  2. Ваш сервер не позволяет вашему приложению создавать так много потоков,linuxКоличество потоков, которые может создать процесс, разрешенное системой по умолчанию.1024Если ваше приложение создает больше, чем это число, об этом будет сообщеноOutOfMemeoryError:unable to create new native thread

Решение:

  1. Найдите способы уменьшить количество потоков, создаваемых вашим приложением, проанализируйте, действительно ли приложению нужно создавать такое количество потоков, и если нет, измените код, чтобы свести к минимуму количество потоков.
  2. Для небольшого приложения нужно создать много потоков, гораздо больше, чем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СлишкомСборщик мусора молодого поколения,использоватькопироватьалгоритм тожепараллельная многопоточностьСборщик мусора, широко известный как сборщик первой пропускной способности.Распараллеливание последовательных коллекторов в молодом и старом поколениях

    关注点:

  1. контролируемая пропускная способность

  2. Стратегия адаптивной корректировки также является важным отличием сборщика ParallelScavenge от сборщика ParallelNew.

    Параметры настройки JVM
    -XX:UseParallelGCили-XX:UseParallelOldGC(можно активировать друг друга), после открытия:Новое поколение использует алгоритм копирования, а старое поколение использует алгоритм маркировки-сопоставления..

старость

  • Серийный GC (серийный старый) / (серийный MSC)
    Serial Old — старая версия сборщика мусора Serial., который также является однопоточным сборщиком, использующимОтметить-организоватьАлгоритм, этот сборщик также в основном работает на сборщике мусора старого поколения по умолчанию на виртуальной машине Java клиента по умолчанию.
    использовать:
  1. В версиях до JDK 1.5 и нового поколенияParallel ScavengeИспользование с коллекторами. (Parallel Scavenge+Serial Old)
  2. В качестве запасной схемы сборки мусора с использованием сборщика 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 ключевых шага:

  1. Initial Mark (初始标记): Прямой доступ к объекту тега GC Root, занимает мало времени.

  2. Concurrent Mark(并行标记): Начиная с объекта, отмеченного на первом этапе, достижимые объекты отмечаются одновременно.

  3. Remark(重新标记): перемаркировать, исправить изменения между объектами и вновь созданными объектами, вызванные запуском пользовательской программы во время параллельной маркировки, что занимает меньше времени.

  4. Concurrent Sweep(并行回收): Сборка мусора выполняется параллельно.

Как выбрать сборщик мусора

  • Один ЦП или небольшая память, автономная программа
    -XX:+UseSerialGC
  • Несколько ЦП, требующих максимальной пропускной способности, например приложения для фоновых вычислений.
    -XX:+UseParallelGC
    -XX:+UseParallelOldGC
  • Несколько процессоров, стремление к малому времени паузы, быстрый отклик, например, интернет-приложения
    -XX:+UseConcMarkSweepGC
    -XX:+ParNewGC

В-четвертых, сборщик мусора G1

Особенности предыдущих сборщиков мусора:

  1. Молодое и старое поколения представляют собой отдельные и непрерывные блоки памяти.
  2. В молодом поколении Eden+S0+S1 использует алгоритм репликации для сбора
  3. Коллекция старого поколения должна сканировать всю область старого поколения
  4. Оба предназначены для выполнения GC как можно меньше и быстрее

Концепция G1:

Garbage-FirstСборщик является сборщиком для серверных приложений.Преимущества заключаются в следующем:

  • Организуйте свободное пространство быстрее
  • Нужно больше времени, чтобы предсказать время паузы GC
  • Не хотите жертвовать большой пропускной способностью
  • Нет необходимости в большой Java-куче

Коллектор G1 предназначен для замены коллектора CMS.

Преимущества G1:

  1. G1 — это сборщик мусора с процессом сортировки памяти, который не приводит к сильной фрагментации памяти.
  2. G1Stop-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

    Инструмент мониторинга статистики

    看完不赞,都是坏蛋
    Не понравилось после прочтения, все хреново
"

Если вы будете усердно работать сегодня, завтра вы сможете сказать на одну вещь меньше, чтобы попросить о помощи!

Я Сяо Цай, человек, который учится у вас. 💋