Первая часть серии JVM: сводка боя по настройке

JVM

предисловие

    В этой статье в основном подводятся итоги некоторых реальных сражений по поводу настройки JVM в технологическом гнезде циветтных кошек, которые можно рассматривать как обобщение моих собственных знаний. В основном на основе двух текущих основных методов сборки мусора, ParNew + CMS и сборщик мусора G1, чтобы разобраться с идеями оптимизации, как читать журналы GC, а также области и причины OOM.

Комбинация ParNew +CMS

ParNew обычно используется в сборщике мусора нового поколения, а CMS - в сборщике мусора старого поколения.Они оба являются многопоточными механизмами параллелизма и имеют лучшую производительность.Сейчас они являются в целом стандартной комбинацией систем онлайн-производства .

Minor GC

Незначительный GC также известен как сборщик мусора молодого поколения.Сборка мусора молодого поколения в основном использует алгоритм репликации.Поскольку большинство объектов молодого поколения «живут и умирают», чтобы уменьшить узкое место использования памяти, область Эдема, Установлены 2 области Survivor и 1 область Eden, занимающая 80% памяти, а каждая Survivor область занимает 10% памяти. Текущий Minor GC в основном использует сборщик мусора ParNew.

Когда пытаться запустить Minor GC?

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

Ситуации, которые запускают Minor GC:

  • Существующие уцелевшие объекты в новом поколении меньше, чем оставшаяся память в старом поколении, то есть места в старом поколении достаточно для поддержки объектов, которые могут быть повышены.
  • Когда случай 1 не установлен, гарантия пространства установлена ​​и гарантия может быть успешной (гарантия пространства включена по умолчанию в текущей версии JDK), то есть пространство старого поколения больше, чем средний размер старое поколение после предыдущего Minor GC.

Что делал Minor GC раньше?

    Определите, меньше ли доступная память старого поколения, чем размер всех объектов в новом поколении. Если да, определите, установлен ли параметр -XX:HandlePromotionFailure. Следующее суждение: посмотрите на память старого поколения.Размер, не больше ли он среднего размера объектов, поступающих в старое поколение после каждого предыдущего Minor GC. Если решение терпит неудачу или гарантия выделения пространства не установлена, полный сборщик мусора будет запущен напрямую, старый возраст будет удален сборщиком мусора, и некоторое пространство будет освобождено, а затем будет выполнен дополнительный сборщик мусора.

Второстепенные результаты ГХ

1. После Minor GC оставшиеся уцелевшие объекты меньше, чем размер области Survivor, и уцелевшие объекты входят в область Survivor.

2. После Minor GC выжившие объекты больше, чем размер области Survivor и меньше, чем доступное пространство старости, и напрямую входят в старость.

3. После Minor GC уцелевшие объекты больше, чем размер области Survivor и размер доступного места в старости.В это время произойдет Handle Promotion.

Old GC

   Старый сборщик мусора также известен как сборщик мусора старого поколения.Сборщики мусора старого возраста в основном включают Serial Old и CMS. Если уцелевшие объекты после Второстепенного GC больше, чем оставшееся пространство в старом возрасте, в это время запускается Старый GC, и объекты, на которые нет ссылок в старом возрасте, восстанавливаются, а затем оставшиеся уцелевшие объекты после Незначительные ГК могут войти в пожилой возраст.

Как предметы входят в старость?

Когда объект выходит из Minor GC 15 раз, соответствует правилам динамического суждения об объекте, больших объектов и объектов после Minor GC слишком много, чтобы их можно было поместить в область Survivor и т. д., это приведет к тому, что объект войдет в старость. будет анализировать каждую сцену одну за другой.

1. Войдите в старое поколение после побега 15 GC
  • Каждый раз, когда объект покидает GC в новом поколении и перемещается в область Survivor, он может увеличить свой возраст только на один год.
  • По умолчанию, когда возраст объекта достигает 15 лет, то есть когда он избежал 15 GC, он будет переведен в зону старой генерации. Конкретный возраст для входа в старость может быть установлен параметром JVM -XX:MaxTenuringThreshold, по умолчанию это 15 лет.
2. Оценка возраста динамического объекта
  • Если после нового поколения gc обнаружено, что в области Survior, где в данный момент находится объект, суммарный размер объектов нескольких возрастов превышает 50% объема памяти этой области Survior, например, сумма размеры объектов age1 + age2 + age3 превышают 50% площади Survivor, затем поместите объекты старше age3 в старость.
  • Правила динамического суждения о возрасте также позволят некоторым объектам нового поколения войти в старость.

    Независимо от того, вступает ли он в старость после 15 GC или правила динамического суждения о возрасте, есть надежда, что объекты, которые могут выжить в течение длительного времени, войдут в старость как можно скорее.

3. Крупные предметы напрямую входят в старость
  • С помощью параметра -XX:PretenureSizeThreshold вы можете установить порог для непосредственного входа объекта в старость.Вы можете установить его значение в количестве байтов, например 1048576 байт, что составляет 1 МБ.
  • Если создается объект больше этого размера, например очень большой массив или другие большие объекты, большой объект в это время непосредственно помещается в старое поколение и вообще не проходит через новое поколение.
4. Слишком много объектов после Minor GC нельзя разместить в зоне Survivor.

    Одна из проблем, которую следует учитывать, заключается в том, что в пожилом возрасте не хватает места для этих объектов. Если размер памяти старого поколения больше, чем у всех объектов в новом поколении, в это время для нового поколения может быть запущен Minor GC, потому что даже если все объекты выживут и область Survivor не сможет поместиться, ее можно перенести к старому поколению. Если перед минорным GC обнаружится, что доступная память старого поколения меньше, чем полный размер нового поколения, то в это время, если все объекты в новом поколении выживут после минорного GC, все они будут перешел на старое поколение.В старом поколении места не хватает.По идее да Есть такая возможность. Таким образом, если перед второстепенным сборщиком мусора обнаружится, что доступная память старого поколения меньше размера всех объектов нового поколения, он проверит, установлен ли параметр -XX:HandlePromotionFailure. Если есть этот параметр, то он продолжит попытки вынести следующее суждение: посмотреть, больше ли размер памяти старого поколения, чем средний размер объектов, попадающих в старое поколение после каждого предыдущего Minor GC. Если решение терпит неудачу или гарантия выделения пространства не установлена, полный сборщик мусора будет запущен напрямую, старое поколение будет удалено сборщиком мусора, и некоторое пространство будет освобождено, а затем будет выполнен дополнительный сборщик мусора.

    Если по-прежнему недостаточно места для хранения оставшихся уцелевших объектов после минорного GC после восстановления старых, это вызовет переполнение памяти OOM.

Как выглядит старый алгоритм сборки мусора?

Алгоритм сопоставления меток

помечает текущие уцелевшие объекты в старости.Эти объекты можно разбросать в памяти, а затем переместить эти уцелевшие объекты в память, отодвинуть уцелевшие объекты как можно дальше в сторону и разместить уцелевшие объекты централизованно чтобы избежать чрезмерной фрагментации памяти после рециркуляции. Затем все объекты мусора собираются в один ряд.

Алгоритм развертки пометки

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

Почему старость не использует алгоритм репликации?

    В старости слишком много уцелевших объектов, при использовании алгоритма копирования 90% уцелевших объектов каждый раз может перемещаться, что не годится. Поэтому метод перемещения уцелевших объектов вместе и их уплотнения сначала, а затем переработка объектов мусора.

Сцена переработки старости

1. Перед минорным сборщиком мусора объем памяти старого поколения меньше, чем средний размер объектов, переведенных в старое поколение после предыдущего минорного сборщика мусора.Если минорный сборщик мусора считается рискованным, старый сборщик мусора может быть запускается заранее для переработки объектов мусора старого поколения.

2. Объектов после Minor GC слишком много, и их нужно продвигать к старому возрасту.Когда оказывается, что места недостаточно, срабатывает Old GC в старом возрасте.

3. Параметр -XX:CMSInitiatingOccuancyFaction установлен, например, он установлен на 92%, например, если использование пространства старого возраста превышает 92%, Старый GC сработает сам по себе.

Процесс утилизации CMS

   CMS делится на 4 этапа в процессе выполнения сборки мусора.

1. Начальная отметка

    Помечает все объекты, на которые непосредственно ссылается GC Roots, что останавливает все рабочие потоки системы и переходит в состояние «Остановить мир».

2. Параллельная маркировка

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

3. Переименовать

    Этот процесс помечает всю кучу, включая молодое и старое поколения.

4. Параллельная очистка

    Найдите мусорные предметы, разбросанные в разных местах, скорость низкая. Наконец, можно выполнить дефрагментацию памяти, чтобы переместить большое количество уцелевших объектов вместе, чтобы освободить непрерывное пространство.Для этого процесса по-прежнему требуется STW, который еще медленнее.

Что такое сбой параллельного режима?

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

Влияние сбоя параллельного режима

  Сборщик мусора старого поколения вырождается из CMS в Serial Old, все потоки приложений приостанавливаются, а время паузы увеличивается.

Возможные причины и решения
  • Причина 1: CMS срабатывает слишком поздно

    Схема: Уменьшить -XX:CMSInitiatingOccupancyFraction=N;

  • Причина 2: слишком много космического мусора

    Решение: включите дефрагментацию пространства и установите период дефрагментации пространства в разумных пределах;

-XX:+UseCMSCompactAtFullCollection (дефрагментация пространства) -XX:CMSFullGCsBeforeCompaction=n, сколько раз выполнять дефрагментацию памяти после полной сборки мусора, по умолчанию 0, что означает, что дефрагментация памяти будет выполняться после каждой полной сборки мусора.

  • Причина 3: Мусор генерируется быстрее, чем очищается Порог продвижения слишком мал; Места для выживших слишком мало, что приводит к переполнению; Площадь Эдема слишком мала, что приводит к увеличению скорости продвижения; есть крупные предметы;

Почему Full GC старого поколения медленнее, чем Minor GC нового поколения?

  • Скорость выполнения нового поколения быстрая, потому что достаточно отслеживать, какие объекты живы прямо из GC Roots.В новом поколении выживших объектов очень мало.Эта скорость очень быстрая, и нет необходимости отслеживать много объектов.После входа в Survivor вы можете напрямую переработать Эдема и Survivor, которого вы использовали ранее.

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

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

  • Наконец, необходимо выполнить дефрагментацию памяти, переместить большое количество уцелевших объектов вместе и очистить пространство памяти, чтобы связаться с пространством памяти.Для этого процесса требуется STW.

  • Во время параллельной очистки, если оставшегося места в памяти недостаточно для хранения объектов, которые будут введены в старое поколение, возникнет проблема «Сбой параллельного режима». В это время будет использоваться сборщик мусора «Serial Old». После STW снова будет проведена старая сборка мусора, что займет больше времени.

Сборщик мусора G1

   Сборщик мусора G1 появился после JDK8.Сборщик мусора G1 определяется параметром -XX:+UseG1GC, который является относительно продвинутым сборщиком мусора. G1 может позволить вам установить влияние сборки мусора на систему.Он делит память на большое количество небольших регионов и отслеживает размер и расчетное время объектов, которые могут быть переработаны в каждом регионе.Наконец, когда происходит сборка мусора , постарайтесь контролировать влияние сборки мусора на систему в течение указанного вами диапазона времени и постарайтесь переработать как можно больше объектов мусора в течение ограниченного времени.

Особенности сборщика мусора G1

  • Разделите память кучи java на несколько областей одинакового размера
  • По логике тоже будут понятия нового поколения и старого поколения
  • Можно установить ожидаемое время паузы для сборки мусора.

проблема с настройкой региона

  • -XX:+UseG1GC для указания сборщика мусора G1.В это время размер кучи будет автоматически делиться на 2048. jvm может иметь до 2048 регионов, и тогда размер региона должен быть кратен 2, например как 1Мб, 2Мб, 4Мб и т.д. Может быть указан с -XX:G1HeapRegionSize.
  • Отношение нового поколения к памяти кучи по умолчанию составляет 5%. Вы также можете использовать -XX:G1NewSizePercent, чтобы установить начальное соотношение нового поколения. Фактически, вы можете сохранить это значение по умолчанию. Когда система работает, JVM будет постоянно добавлять больше регионов к новому поколению, но доля нового поколения не превышает максимум 60%, что можно установить с помощью -XX:G1MaxNewSizePercent.

Как перерабатывается G1 нового поколения?

    Новое поколение также делится на эден и выживший, а размер эдена и выжившего можно разделить на -XX:SurvivorRatio. Механизм запуска сборки мусора аналогичен: поскольку объекты постоянно размещаются в регионе, соответствующем eden нового поколения, jvm будет продолжать добавлять новые регионы в новое поколение до тех пор, пока новое поколение не составит 60% от максимального размера кучи. Например, в новом поколении 1200 регионов, эдем в нем может занимать 1000 регионов, каждый выживший - это 100 регионов, а область эдема еще заполнена объектами, то сработает гк нового поколения.Алгоритм репликации S1 выполняет сборку мусора, переходит в состояние STW, одновременно помещает уцелевшие объекты из области, соответствующей eden, в область S1, а затем перерабатывает мусорные объекты в области, соответствующей eden.    g1 может установить целевое время паузы gc, то есть, как долго система может приостанавливаться, когда g1 выполняет gc, что можно установить с помощью параметра -XX:MaxGCPauseMills, значение по умолчанию — 200 мс.

Когда объект G1 входит в старое поколение из молодого поколения?

  • Объект избежал многих сборок мусора в новом поколении и достиг определенного возраста, параметр -XX:MaxTenuringThreshold может установить этот возраст, и он войдет в старость.
  • Правило динамического определения возраста.Если установлено, что после определенного GC нового поколения выжившие объекты превышают 50% Survivor, а сумма размеров объектов, таких как возраст 1, 2, 3 и 4 года , превышает Survivor.В это время все объекты старше 4 лет входят в старость, что является правилом динамического определения возраста

Крупный объект Район

    Для модели памяти G1 G1 предоставляет выделенный регион для хранения больших объектов, вместо того, чтобы позволить крупным объектам попадать в регион старости. В G1 правило оценки для больших объектов заключается в том, что большой объект превышает 50% области. Например, область составляет 2 МБ. Пока большой объект превышает 1 МБ, он будет помещен в область, предназначенную для больших объектов, и большой объект будет помещен в область, предназначенную для больших объектов.Слишком большие объекты могут храниться в нескольких областях. Когда новое поколение и старое поколение будут переработаны, они будут переработаны вместе с большими объектами.

Смешанная сборка мусора нового поколения + старого поколения

G1 имеет параметр -XX:InitiatingHeapOccupancyPercent, значение по умолчанию — 45%.Если старое поколение занимает 45% области памяти кучи, оно попытается инициировать смешанную фазу восстановления, в которой новое поколение + старое поколение перерабатываются вместе.

Процесс сборки мусора G1

  • Начальная маркировка Просто отметьте объекты, на которые может напрямую ссылаться GC Roots.Этот процесс очень быстрый и требует перехода в состояние STW.
  • Параллельная маркировка Эта фаза позволяет запускать системные программы во время отслеживания корней GC.Все выжившие объекты отслеживаются из корней GC.Параллельная фаза по-прежнему занимает много времени, поскольку необходимо отслеживать все выжившие объекты. Однако этот этап может выполняться одновременно с системной программой, поэтому влияние на системную программу не слишком велико. И JVM запишет некоторые изменения, внесенные в объект на этапе параллельной маркировки, например, какой объект был создан и какой объект потерял свою ссылку.
  • Окончательная маркировка На этом этапе войдет STW, запуск системной программы запрещен, но она будет изменена в соответствии с объектами, записанными на параллельной стадии маркировки, и, наконец, будет отмечена, какие объекты являются живыми, а какие — мусором.
  • Смешанная сборка На этом этапе вычисляется количество уцелевших объектов в каждом регионе в старом поколении, доля уцелевших объектов, а также ожидаемая производительность и эффективность выполнения сборки мусора. Затем системная программа будет остановлена, а затем будут предприняты все усилия для скорейшей сборки мусора, в это время будут выбраны некоторые Регионы для утилизации, т.к. уточнить. Смешанная сборка выберет некоторые регионы из нового поколения, старого поколения и больших объектов, чтобы обеспечить сбор как можно большего количества мусора в течение заданного времени (например, 200 мс).

Некоторые параметры сборщика мусора G1

  • -XX:G1MixedGCCountTarget, то есть в процессе смешанной коллекции последний этап выполняет несколько смешанных сборов, и значение по умолчанию равно 8 раз. Это означает, что на последнем этапе система сначала останавливается, некоторые Регионы смешиваются и восстанавливаются, затем возобновляется работа системы, затем система снова отключается, а некоторые Регионы смешиваются и перерабатываются, повторяется 8 раз. Значение повторной перезапуска заключается в том, чтобы система не простаивала как можно дольше, и вы также можете запускать ее в промежутке между несколькими повторами.
  • -XX:G1HeapWastePercent, значение по умолчанию 5%.При смешанном восстановлении восстановление региона основано на алгоритме репликации, заключающемся в помещении уцелевших объектов восстанавливаемого региона в другие регионы, а затем мусора в этом регионе. .Объекты все очищены. В этом случае новые регионы постоянно освобождаются в процессе рециркуляции, как только количество свободных регионов достигает 5% памяти кучи, смешанная коллекция будет немедленно остановлена, что означает, что эта смешанная коллекция будет закончена, то есть , 4 После первого смешанного восстановления обнаруживается, что область бездействия достигает 5%, и последующее смешанное восстановление выполняться не будет. Из этого также видно, что G1 в целом основан на алгоритме репликации для сборки мусора Region, и здесь нет проблемы фрагментации памяти, ему не нужно маркировать-очищать, как CMS, а затем выполнять фрагментацию памяти.
  • -XX:G1MixedGCLiveThresholdPercent, значение по умолчанию — 85%, когда в регионе более 85% уцелевших объектов, он не будет переработан в это время. Потому что стоимость копирования в другие регионы тоже очень высока.

Полный сборщик мусора при сбое сбора

При смешанной переработке происходит переработка как молодого, так и старого поколения по алгоритму копирования, при этом уцелевшие объекты каждого региона должны быть скопированы в другие регионы В случае отсутствия свободного региона в процессе копирования Размещение собственного уцелевшего объекта вызовет сбой. В случае сбоя он немедленно переключается на остановку системной программы, а затем использует один поток для маркировки, очистки, сжатия и освобождения пакета регионов.Этот процесс очень медленный.

Как оптимизировать параметры JVM?

Сборщик мусора G1

Оптимизация нового поколения G1

  • Выделите достаточно памяти для всей области кучи JVM
  • Разумно установить параметр -XX:MaxGCPauseMills, настройка параметра небольшая, время паузы каждого gc может быть очень коротким, а частота gc увеличена. Если значение параметра слишком велико, возможно, что G1 будет продолжать выделять новые объекты в новом поколении, а затем накапливать много объектов, а затем освобождать сотни регионов одновременно.

смешанная оптимизация сборщика мусора

   Старость занимает более 45% памяти кучи и запускает смешанный gc Идея оптимизации состоит в том, чтобы попытаться избежать слишком быстрого старения объектов и попытаться избежать частого запуска смешанного gc. Суть оптимизации заключается в том, чтобы не допустить достижения старым возрастом значения, установленного параметром InitiatingHeapOccupancyPercent, то есть предотвратить слишком быстрое старение объектов.

  • 1. Пусть мусорные объекты как можно быстрее перерабатываются в новом поколении, и старайтесь не допускать попадания короткоживущих объектов в старое поколение. То есть разумная установка значения -XX:SurvivorRatio.
  • 2. Увеличьте значение InitiatingHeapOccupancyPercent при запуске смешанного gc, чтобы уменьшить вероятность смешанного gc, но это увеличит вычислительную нагрузку при повторном использовании gc.
  • 3. Разумно настроить значение параметра -XX:MaxGCPauseMills, чтобы его новое поколение gc не было слишком частым, но также учитывать, сколько уцелевших объектов после каждого gc, чтобы избежать слишком большого количества уцелевших объектов, быстро зайти в старое возраста, и часто встречаются триггерные смешанные gc.

сборщик мусора parnew+cms

    Разумно распределяйте память кучи и контролируйте скорость входа в старые объекты, регулируя размер области s и области e, тем самым уменьшая частый старый сбор мусора.

Сравнение двух сборщиков мусора

  1. Самая большая разница между переработкой parnew+cms и g1 заключается в том, будет ли переработана вся куча.
  2. g1 может установить расчетное время паузы, подходящее для приложений с малой задержкой
  3. G1 использует алгоритм репликации в целом, который подходит для приложений, генерирующих большое количество фрагментов.
  4. Сборщик parnew+cms больше подходит для приложений с небольшим объемом памяти и коротким временем жизни объектов в новом поколении, g1 подходит для вычислительных приложений с большим объемом памяти, поскольку восстановление всей кучи займет много времени.

Интерпретация журналов gc

    Научившись интерпретировать журналы сборщика мусора, можно хорошо анализировать использование кучи, что является важным навыком для настройки и решения частых полных сборщиков мусора. Давайте возьмем сборщик мусора parnew+cms в качестве примера для анализа журнала gc.

Кайнозойский каротаж ГХ

public class JvmTest {

    public static void main(String[] args) {
        byte[] array1 = new byte[1024*1024];
        array1 = new byte[1024*1024];
        array1 = new byte[1024*1024];
        array1 = null;

        byte[] array2 = new byte[2*1024*1024];
    }
}

0.268: [GC (Allocation Failure) 0.269: [ParNew: 4030K->512K(4608K), 0.0015734 secs] 4030K->574K(9728K), 0.0017518 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

Heap

par new generation total 4608K, used 2601K [0x00000000ff600000, 0x00000000ffb00000, 0x00000000ffb00000)
eden space 4096K, 51% used [0x00000000ff600000, 0x00000000ff80a558, 0x00000000ffa00000)
from space 512K, 100% used [0x00000000ffa80000, 0x00000000ffb00000, 0x00000000ffb00000)
to space 512K, 0% used [0x00000000ffa00000, 0x00000000ffa00000, 0x00000000ffa80000)

concurrent mark-sweep generation total 5120K, used 62K [0x00000000ffb00000, 0x0000000100000000, 0x0000000100000000)

Metaspace used 2782K, capacity 4486K, committed 4864K, reserved 1056768K class space used 300K, capacity 386K, committed 512K, reserved 1048576K

  • 0,268 означает, что gc запускается после того, как система работает в течение 268 миллисекунд.
  • GC (ошибка распределения) означает, что выделение объекта не приводит к запуску GC.
  • [ParNew: 4030K->512K(4608K), 0,0015734 с] ParNew указывает на сборщик мусора для молодого поколения, 4608k указывает на свободное пространство для молодого поколения в размере 4,5 МБ, что соответствует размеру области eden + 1 область выживания. 4030K->512K означает, что до GC использовалось 4030K, а после GC осталось только 512K объектов.
  • 4030K->574K(9728K); 4030K означает, что 4030K используется во всей куче перед сборкой мусора, 574K используется после gc, а размер всей кучи составляет 9728K.
  • 0,0015734 с означает, что сборка мусора занимает 1,5 мс. Примечание. До GC в области Eden было три массива по 1 МБ, всего 3 МБ, что составляет 3072 КБ объектов, но для хранения этого массива JVM 0,268: [GC (ошибка размещения) 0,269: [ParNew: 4030K->512K(4608K), 0,0015734 с] 4030K->574K(9728K), 0,0017518 с] [Times: user=0,00 sys=0,00, real=0,00 с]

Когда JVM завершает работу, печатается текущее использование памяти кучи.Анализ выглядит следующим образом:

  • par новое поколение всего 4608 КБ, использовано 2601 КБ, что указывает на то, что молодое поколение, отвечающее за сборщик мусора ParNew, имеет в общей сложности 4608 КБ доступной памяти и в настоящее время использует 2601 КБ.
  • из космоса, использовано на 100%; это указывает на то, что неизвестные объекты размером 512 КБ, пережившие предыдущую сборку мусора, займут пространство из космоса
  • to space, используется 0%; одновременно нельзя использовать области from space и to space, одна из которых хранится после предыдущего уцелевшего объекта gc, а другая простаивает.
  • concurrent mark-sweep Generation total 5120K, used 62K;указывает на то, что используется сборщик мусора Concurrent Mark-Sweep, то есть сборщик мусора CMS.Общий объем памяти старого поколения составляет 5МБ, а на данном используется 62КБ пространства время.

Анализ использования метапространства

   Метапространство отделено от виртуального адресного пространства процесса JVM для хранения метаданных класса. JVM сохраняет начальный размер при запуске в соответствии с параметром -XX:MetaspaceSize, который имеет значение по умолчанию для конкретной платформы.

   Metaspace состоит из одного или нескольких виртуальных пространств. Виртуальное пространство — это непрерывное адресное пространство, полученное операционной системой. Они выделяются по запросу. В момент выделения виртуальное пространство резервирует (резервирует) память для операционной системы, но еще не зафиксировало. Зарезервированное метапространство — это общий размер всех виртуальных пространств. Единицей выделения в виртуальном пространстве является Metachunk, при выделении нового блока из виртуального пространства будет зафиксирована соответствующая память, а зафиксированное Metaspace — это общий размер всех блоков. отdocs.Oracle.com/java-color/8/do…Вы можете получить обзор и объяснение использованной, зафиксированной, зарезервированной и емкости;

In the line beginning with Metaspace, the used value is the amount of space used for loaded classes. The capacity value is the space available for metadata in currently allocated chunks. The committed value is the amount of space available for chunks. The reserved value is the amount of space reserved (but not necessarily committed) for metadata. The line beginning with class space line contains the corresponding values for the metadata for compressed class pointers.

  • используемое представляет пространство загруженного класса, емкость представляет собой пространство текущего выделенного блока (несвободного блока), который меньше, чем выделенное пространство; зафиксированный означает, что когда новый блок выделяется из виртуального пространства, соответствующая память будет зафиксировано, то есть было зафиксировано Размер доступного блока распределения, представленного приложением, должен быть больше, чем используемый; зарезервировано относится к общему размеру метапространства, пространство разделено на блоки, и каждый блок может содержат только метаданные класса, связанные с определенным загрузчиком класса. Для определения и объяснения этих параметров, пожалуйста, обратитесь к статье:Woohoo.Краткое описание.com/afraid/Chengdu 34 6 раундов и 3...
  • Пространство классов относится к сумме памяти, которая фактически используется для размещения классов, и это будет подробно проанализировано в будущем.

Полный анализ журнала сборщика мусора

   Полный сборщик мусора имеет следующие симптомы, такие как слишком высокая загрузка ЦП компьютера, система не может обработать запрос или обработка выполняется слишком медленно. Есть много причин для полного GC, в основном в том числе необоснованные настройки параметров JVM и проблемы на уровне кода. Необоснованные настройки параметров JVM, такие как необоснованная установка размера кучи памяти нового поколения, необоснованная установка соотношения Eden и Survivor или установка слишком малого метапространства. Проблемы на уровне кода — это в основном собственные проблемы программиста, например, нет ограничений на предоставление внешних интерфейсов запросов, одновременно запрашивается слишком много объектов, в приложении частые и большие экспорты, нет ограничения на запрос, в коде показан вызов gc и т.д.

public class FullGCTest {
    public static void main(String[] args) {
        byte[] array1 = new byte[4*1024*1024];
        array1 = null;
        byte[] array2 = new byte[2*1024*1024];
        byte[] array3 = new byte[2*1024*1024];
        byte[] array4 = new byte[2*1024*1024];
        byte[] array5 = new byte[128*1024];
        byte[] array6 = new byte[2*1024*1024];
    }
}

Объединив приведенную выше конфигурацию, мы можем обнаружить, что большой объект массива array1 сразу войдет в старость; после этого последовательно выделяются 4 массива, 3 из которых — массивы по 2 МБ и 1 — массивы по 128 КБ, все они войдут в Район Эдем. При перераспределении массива6 будет обнаружено, что в области eden недостаточно места, и необходимо запустить второстепенный сборщик мусора.Однако, поскольку на массив2, массив3, массив4 и массив5 ссылаются переменные, они будут напрямую войти в старость, потому что в старости уже 4Мб данных. , хранить такой большой объем данных сложно, поэтому будет срабатывать Full GC. Полная сборка мусора будет выполнять старую сборку мусора в старом возрасте и обычно связана с молодой сборкой мусора, а также запускает метапространственную сборку мусора. Давайте проанализируем журнал сборщика мусора ниже.

0.308: [GC (Allocation Failure) 0.308: [ParNew (promotion failed): 7260K->7970K(9216K), 0.0048975 secs]0.314: [CMS: 8194K- >6836K(10240K), 0.0049920 secs] 11356K->6836K(19456K), [Metaspace: 2776K->2776K(1056768K)], 0.0106074 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]

Heap

par new generation total 9216K, used 2130K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)

eden space 8192K, 26% used [0x00000000fec00000, 0x00000000fee14930, 0x00000000ff400000)

from space 1024K, 0% used [0x00000000ff500000, 0x00000000ff500000, 0x00000000ff600000)

to space 1024K, 0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff500000)

concurrent mark-sweep generation total 10240K, used 6836K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)

Metaspace used 2782K, capacity 4486K, committed 4864K, reserved 1056768K class space used 300K, capacity 386K, committed 512K, reserved 1048576K

  • ParNew (продвижение не выполнено): 7260K->7970K(9216K), 0,0048975 сек. До переработки в районе Эдема находится более 7000 КБ объектов, но после переработки выясняется, что ни один из них не может быть переработан, в основном из-за вышеуказанного на массивы ссылаются переменные происходит продвижение Основная причина сбоя в том, что во время Minor GC нельзя разместить Survivor Space, а объект можно разместить только в старости, а старость в это время поставить нельзя .
  • CMS: 8194K->6836K(10240K), 0,0049920 с; это указывает, что размер старого объекта до старого gc составляет 8194 КБ, размер оставшихся объектов после старого gc составляет 6836 КБ, а общий размер пространства старого составляет 10240К. Увидев это, может возникнуть сомнение, а почему до старого gc объектов 8194К? В основном это связано с тем, что два объекта размером 2 МБ помещаются в старость после молодого gc. Продолжайте хранить 1 массив 2 МБ и 1 массив 128 КБ в старости, если его нельзя проставить, срабатывает Full GC.
  • 11356K->6836K (19456K); это показывает, что вся куча использовала 11356K до старой сборки мусора и 6836K использовалась после старой сборки мусора.

Далее анализируется использование памяти кучи после полной сборки мусора.

  • номинал нового поколения всего 9216 КБ, использовано 2130 КБ; после полного GC оставшиеся 2 МБ хранятся в области enden.
  • из космоса 1024K, использовано 0%, нет уцелевших объектов при молодом gc;
  • to space 1024K, используется 0%, to space сам по себе в этом gc не участвует, и сценария использования нет;
  • общее количество одновременных меток-очисток 10240 КБ, использовано 6836 КБ, что указывает на то, что с помощью сборщика мусора CMS все 6836 КБ объектов в новом поколении вошли в старое поколение;

    По возможности выжившие объекты после каждого Молодого GC составляют менее 50% площади Survivor и остаются в молодом поколении. Старайтесь не впускать объект Вступительный возраст. Минимизируйте частоту полного GC, чтобы избежать влияния частого полного GC на производительность JVM.

Как определить параметры jvm при выходе в интернет?

После того, как система проходит одиночный тест, набор тестов и тестовую среду, она входит в предварительную среду для стресс-тестирования, наблюдает за использованием памяти, частотой срабатывания Young GC, затратами времени на Young GC и тем, как сколько объектов пережило каждый молодой GC. Сколько объектов вступило в старость после Young GC, скорость роста объектов в старости и частота срабатывания полного GC.

Получите pid процесса java с помощью ps -ef | grep java и используйте инструмент jstat для просмотра ситуации gc;

[tian~]$ jstat -gc 2236
 S0C    S1C    S0U    S1U      EC    EU        OC        OU        MC      MU      CCSC    CCSU      YGC     YGCT    FGC     FGCT     GCT   
20480.0 20480.0 269.9 0.0  163840.0 97683.3  319488.0  271892.4  673268.0 661182.8 78048.0 75954.8   508    9.526    18      1.737   11.263
S0C:这是From Survivor区的⼤⼩
S1C:这是To Survivor区的⼤⼩
S0U:这是From Survivor区当前使⽤的内存⼤⼩
S1U:这是To Survivor区当前使⽤的内存⼤⼩
EC:这是Eden区的⼤⼩
EU:这是Eden区当前使⽤的内存⼤⼩
OC:这是⽼年代的⼤⼩
OU:这是⽼年代当前使⽤的内存⼤⼩
MC:这是⽅法区(永久代、元数据区)的⼤⼩
MU:这是⽅法区(永久代、元数据区)的当前使⽤的内存⼤⼩
YGC:这是系统运⾏迄今为⽌的Young GC次数
YGCT:这是Young GC的耗时
FGC:这是系统运⾏迄今为⽌的Full GC次数
FGCT:这是Full GC的耗时
GCT:这是所有GC的总耗时

Вы можете использовать команду jstat -gc PID 1000 10, чтобы обновлять последнюю строку статистики jstat каждую 1 с, выполнять в общей сложности 10 статистических данных и наблюдать за изменениями занятости объектов в области eden jvm через равные промежутки времени. . Если объем доступа к системе невелик, время наблюдения можно соответствующим образом увеличить, чтобы можно было приблизительно оценить продолжительность каждой паузы gc. Есть также лучшие инструменты визуального мониторинга, такие как JVisualVM и Cat.

Общие параметры ГХ

-Xmx8g -Xms8g -Xmn2g -Xss256k  Xms、Xmx表示堆的大小,Xmn表示年轻代大小,Xss表示线程栈擦小,默认1M
-XX:SurvivorRatio=2 新生代中Eden与Survivor比值,调优的关键,也就是调节新生代堆大小及SurvivorRatio的值,尽量让新生代垃圾对象存放在Survivor中;
-XX:MetaspaceSize=256m  
-XX:MaxMetaspaceSize=256m 元空间大小
-XX:+UseParNewGC 用并行收集器 ParNew 对新生代进行垃圾回收
-XX:+UseConcMarkSweepGC 并发标记清除收集器 CMS 对老年代进行垃圾回收。
-XX:ParallelGCThreads=2 Young GC工作时的并行线程数
-XX:ParallelCMSThreads=3 CMS GC 工作时的并行线程数
-XX:+CMSParallelRemarkEnabled 并行运行最终标记阶段,加快最终标记的速度
-XX:+CMSParallelInitialMarkEnabled 初始阶段开启多线程并发执行,减少STW时间
-XX:+CMSScavengeBeforeRemark 在CMS重新标记阶段之前,执行一次Young GC,因为重新标记是整堆标记的,执行一次Young GC,回收调年轻代里没人引用的对象,减少扫描对象。
-XX:MaxTenuringThreshold=15 对象从新生代晋升到老年代的年龄阈值(每次 Young GC 留下来的对象年龄加一),默认值15
-XX:+UseCMSCompactAtFullCollection 开启碎片整理
-XX:CMSFullGCsBeforeCompaction=2 与-XX:+UseCMSCompactAtFullCollection配合使用,表示进行2次Full GC后进行整理
-XX:+UseCMSInitiatingOccupancyOnly 只根据老年代使用比例来决定是否进行CMS
-XX:CMSInitiatingOccupancyFraction=80 设置触发CMS老年代回收的内存使用率占比,达到80%时触发old gc
-XX:+CMSClassUnloadingEnabled 默认开启,表示开启 CMS 对元空间的垃圾回收,避免由于元空间耗尽带来 Full GC
-XX:-DisableExplicitGC 禁止代码中显示调用GC
-XX:+HeapDumpOnOutOfMemoryError OOM时dump内存快照
-verbose:gc 表示输出虚拟机中GC的详细情况
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintGCDateStamps
-Xloggc:/app/log/xxx.log gc文件未知

OOM-анализ

    Существует три основных области, в которых происходит OOM: одна — это область метапространства, одна — память стека виртуальной машины, а другая — пространство кучи памяти.

Переполнение метапространства памяти

При полной сборке мусора он обязательно попытается вернуть классы в области метапространства.Конечно, условия восстановления относительно жесткие.Например, сначала должен быть восстановлен загрузчик классов этого класса, а все экземпляры объектов класса должны быть восстановлены. после того, как область метапространства заполнена классами, возможно, она не сможет повторно использовать многие классы в ней. JVM не освобождает слишком много места. По мере выполнения программы она будет продолжать вставлять новые классы в область метапространства, что напрямую вызовет проблему переполнения памяти. Причины переполнения памяти Metaspace

  • Насколько мала настройка Metaspace;
  • Большое количество технологий, таких как cglib, используется для динамической генерации некоторых классов, что приводит к созданию слишком большого количества классов, заполнению метапространства и переполнению памяти;

переполнение стека

    Размер стека виртуальной машины каждого потока фиксирован. Когда поток вызывает метод, он помещает кадр стека вызова этого метода в стек виртуальной машины. В этой подушке стека есть локальные переменные метода. Основной причиной переполнения стека является возникновение рекурсивных вызовов классов.

переполнение кучи памяти

Основная причина переполнения динамической памяти в том, что уцелевшие объекты продолжают поступать в старость в области eden.После срабатывания full gc обнаруживается, что в старости меньше переработанных объектов, по-прежнему остается большое количество уцелевших объектов в старости, а в молодом поколении все еще есть ряд объектов, ожидающих помещения в старость.Нет, в это время выдается исключение переполнения памяти. Вообще говоря, есть два основных сценария, которые вызывают переполнение памяти:

  • Система выполняет большое количество одновременных запросов.Поскольку объем запросов слишком велик, большое количество объектов все еще живы.Поэтому невозможно продолжать размещать новые объекты, что приведет к сбою системы OOM.
  • В системе есть проблема с утечками памяти, то есть множество объектов необъяснимо манипулируют, и в результате объекты все живы, а ссылки на них вовремя не отменяются, в результате чего GC срабатывает и до сих пор не может для повторного использования.В настоящее время это может вызвать только переполнение памяти, потому что память слишком не может помещать больше объектов. Таким образом, подводя итог, обычно вызывается OOM, либо слишком высокая загрузка системы, либо проблема с утечкой памяти.