Что такое garbage collector java

Избавляемся от мусора в Java

Что такое garbage collector java. Смотреть фото Что такое garbage collector java. Смотреть картинку Что такое garbage collector java. Картинка про Что такое garbage collector java. Фото Что такое garbage collector java

Что такое сборка мусора, зачем она нужна и как работает

Для работы любого приложения требуется память. Однако память компьютера ограничена. Поэтому важно ее очищать от старых неиспользуемых данных, чтобы освободить место для новых.

Кто занимается этой очисткой? Как и когда очищается память? Как выглядит структура памяти? Давайте разберем с этим подробнее.

Структура памяти Java

Память в Java состоит из следующих областей:

Что такое garbage collector java. Смотреть фото Что такое garbage collector java. Смотреть картинку Что такое garbage collector java. Картинка про Что такое garbage collector java. Фото Что такое garbage collector javaСтруктура памяти Java

Native Memory — вся доступная системная память.

Stack (стек) — используется для хранения локальных переменных и стека вызовов метода. Для каждого потока выделяется свой стек.

Metaspace (метаданные) — в этой памяти хранятся метаданные классов и статические переменные. Это пространство также является общими для всех. Так как metaspace является частью native memory, то его размер зависит от платформы. Верхний предел объема памяти, используемой для metaspace, можно настроить с помощью флага MaxMetaspaceSize.

PermGen (Permanent Generation, постоянное поколение) присутствовало до Java 7. Начиная с Java 8 ему на смену пришла область Metaspace.

CodeCache (кэш кода) — JIT-компилятор компилирует часто исполняемый код, преобразует его в нативный машинный код и кеширует для более быстрого выполнения. Это тоже часть native memory.

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

Что такое «мусор»? Мусором считается объект, который больше не может быть достигнут по ссылке из какого-либо объекта. Поскольку такие объекты больше не используются в приложении, то их можно удалить из памяти.

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

Что такое garbage collector java. Смотреть фото Что такое garbage collector java. Смотреть картинку Что такое garbage collector java. Картинка про Что такое garbage collector java. Фото Что такое garbage collector javaМусор

Что такое сборка мусора? Сборка мусора — это процесс автоматического управления памятью. Освобождение памяти (путем очистки мусора) выполняется автоматически специальным компонентом JVM — сборщиком мусора (Garbage Collector, GC). Нам, как программистам, нет необходимости вмешиваться в процесс сборки мусора.

Что такое garbage collector java. Смотреть фото Что такое garbage collector java. Смотреть картинку Что такое garbage collector java. Картинка про Что такое garbage collector java. Фото Что такое garbage collector javaИсточник: Oracle.com

Сборка мусора: процесс

Для сборки мусора используется алгоритм пометок (Mark & Sweep). Этот алгоритм состоит из трех этапов:

Sweep (очистка). На этом шаге освобождается память, занятая объектами, не отмеченными на предыдущем шаге.

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

Что такое garbage collector java. Смотреть фото Что такое garbage collector java. Смотреть картинку Что такое garbage collector java. Картинка про Что такое garbage collector java. Фото Что такое garbage collector javaMark & Sweep GC

Поколения объектов

Что такое поколения объектов?

Для оптимизации сборки мусора память кучи дополнительно разделена на четыре области. В эти области объекты помещаются в зависимости от их возраста (как долго они используются в приложении).

Young Generation (молодое поколение). Здесь создаются новые объекты. Область young generation разделена на три части раздела: Eden (Эдем), S0 и S1 (Survivor Space — область для выживших).

Old Generation (старое поколение). Здесь хранятся давно живущие объекты.

Что такое garbage collector java. Смотреть фото Что такое garbage collector java. Смотреть картинку Что такое garbage collector java. Картинка про Что такое garbage collector java. Фото Что такое garbage collector javaПоколения в куче

Что такое Stop the World?

Когда запускается этап mark, работа приложения останавливается. После завершения mark приложение возобновляет свою работу. Любая сборка мусора — это «Stop the World».

Что такое гипотеза о поколениях?

Как уже упоминалось ранее, для оптимизации этапов mark и sweep используются поколения. Гипотеза о поколениях говорит о следующем:

Большинство объектов живут недолго.

Если объект выживает, то он, скорее всего, будет жить вечно.

Этапы mark и sweep занимают меньше времени при большом количестве мусора. То есть маркировка будет происходить быстрее, если анализируемая область небольшая и в ней много мертвых объектов.

Таким образом, алгоритм сборки мусора, использующий поколения, выглядит следующим образом:

Что такое garbage collector java. Смотреть фото Что такое garbage collector java. Смотреть картинку Что такое garbage collector java. Картинка про Что такое garbage collector java. Фото Что такое garbage collector javaСборка мусора поколениями

    Новые объекты создаются в области Eden. Области Survivor (S0, S1) на данный момент пустые.

    Когда область Eden заполняется, происходит минорная сборка мусора (Minor GC). Minor GC — это процесс, при котором операции mark и sweep выполняются для young generation (молодого поколения).

    После Minor GC живые объекты перемещаются в одну из областей Survivor (например, S0). Мертвые объекты полностью удаляются.

    По мере работы приложения пространство Eden заполняется новыми объектами. При очередном Minor GC области young generation и S0 очищаются. На этот раз выжившие объекты перемещаются в область S1, и их возраст увеличивается (отметка о том, что они пережили сборку мусора).

    При следующем Minor GC процесс повторяется. Однако на этот раз области Survivor меняются местами. Живые объекты перемещаются в S0 и у них увеличивается возраст. Области Eden и S1 очищаются.

    Объекты между областями Survivor копируются определенное количество раз (пока не переживут определенное количество Minor GC) или пока там достаточно места. Затем эти объекты копируются в область Old.

    Major GC. При Major GC этапы mark и sweep выполняются для Old Generation. Major GC работает медленнее по сравнению с Minor GC, поскольку старое поколение в основном состоит из живых объектов.

    Преимущества использования поколений

    Minor GC происходит в меньшей части кучи (

    2/3 от кучи). Этап маркировки эффективен, потому что область небольшая и состоит в основном из мертвых объектов.

    Недостатки использования поколений

    В каждый момент времени одно из пространств Survivor (S0 или S1) пустое и не используется.

    Сборка мусора: флаги

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

    Флаг

    Описание

    Первоначальный размер кучи

    Максимальный размер куча

    Отношение размера Old Generation к Young Generation

    Отношение размера Eden к Survivor

    Возраст объекта, когда объект перемещается из области Survivor в область Old Generation

    Типы сборщиков мусора

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

    Описание

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

    Когда использовать

    Флаги для включения

    Использует один поток.

    Эффективный, т.к. нет накладных расходов на взаимодействие потоков.

    Работа с небольшими наборами данных.

    Использует несколько потоков.

    Многопоточность ускоряет сборку мусора.

    В приоритете пиковая производительность.

    Допустимы паузы при GC в одну секунду и более.

    Работа со средними и большими наборами данных.

    Для приложений, работающих на многопроцессорном или многопоточном оборудовании.

    Выполняет некоторую тяжелую работу параллельно с работой приложения.

    Может использоваться как на небольших системах, так и на больших с большим количеством процессоров и большим количеством памяти.

    Когда время отклика важнее пропускной способности.

    Паузы GC должны быть меньше одной секунды.

    Выполняет всю тяжелую работу параллельно с работой приложения.

    В приоритете время отклика.

    Сборщики мусора в Java

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

    Что мониторить?

    Частота запуска сборки мусора. Так как GC вызывает «stop the world», поэтому чем время сборки мусора меньше, тем лучше.

    Длительность одного цикла сборки мусора.

    Как мониторить сборщик мусора?

    Для мониторинга можно использовать следующие инструменты:

    Для включения логирования событий сборщика мусора добавьте следующие параметры JVM:

    Источник

    ziginsider

    Функции

    Garbage Collector (GB) часть JVM, который призван очищать память, выделенную приложению. Он должен:

    Есть различные реализации GB.

    Поиск мусора

    Организация памяти JVM

    Делится на две части:

    Heap. Куча. Тут и работает GC.

    Делится на две области:

    Алгоритм GC исходит из того предположения, что большинство java-объектов живут недолго. Быстро становятся мусором. От них необходимо довольно оперативно избавляться. Что и происходит в New Generation. Там сбор мусора гораздо чаще, чем в Old Generation, где хранятся долгоживущие объекты. После создания объект попадает в New Generation и имеет шанс попасть в Old Generation по прошествии некоторого времени (циклов GC).

    Размер Heap настраивается.

    Принцип работы 4 сборщиков HotSpot VM (одна из JVM)

    Serial. Когда нет места в Eden, запускается GC, живые объекты коприруются в S1. Вся область Eden очищается. S1 и S2 меняются местами. При последующих циклах в S1 будут записаны живые объекты как из Eden, так и из S2. После нескольких циклов обмена S1 и S2 или заполнения области S2, обекты, которые живут достаточно долго перемещаются в Old Greneration.

    Следует сказать, что не всегда объекты при создании аллоцируюся в Eden. Если объект слишком велик, он сразу идет в Old Generation.

    Когда после очередной сборки мусора места нехватает уже в New Generation, то запускается сбор мусора в Old Generation (наряду со сборкой New Generation). В old Generation объекты уплотняются (алгоритм Mark-Sweep-Compact).

    Если после полной сборки мусора места нехватает, то вылетает Java.lang.OutOfMemoryError.

    Но во время работы VW может запрашивать увеличение памяти и Heap может увеличиваться.

    Как правило, Old Generation занимает 2/3 объема Heap.

    Parallel. То же, что и Serial, но использует для работы несколько потоков. Таким образом STW чуть меньше.

    Concurent Mark Sweep. Принцип работы с New Generation такой же, как и в случае алгоритмов Serial и Parallel, отличия в том, что данный алгоритм разделяет младшую (New Generation) и старшую (Old Generation) сборку мусора во времени. Причем сбор мусора в Old Generation происходит в отдельном потоке, независимо от младшей сборки. При этом сначала приложение останавливается, сборщик помечает все живые объекты доступные из GC Root (корневых точек) напрямую, затем приложение вновь начинает работу, а сбощик проверяет объекты доступные по ссылкам из этих самых помеченных, и также помечает их как живые. Эта особенность создает так называемые плавающие объекты, которые помечены как живые, но таковыми по факту не являющимися. Но они будут удалены в следующих циклах. Т.е. пропускная способность растет, STW уменьшается, но требутся больше места для хранения плавающих объектов.

    В этом алгоритме уплотнения нет. Т.е. область Old Generation дефрагментированна.

    Garbage-First. G1 сильно отличается от своих предшественников. Он делит область Heap не физически, а скорее логически на те же области: Eden, Survivor, Old Generation. Причем дефрагментированно. Физически область Heap делится на регионы одинакового размера, каждый из которых может быть Eden, Survivor или Old Generation + область для больших объектов (громадный регион).

    А с полной сборкой (точнее, здесь она называется смешанной (mixed)) все немного хитроумнее, чем в рассмотренных ранее сборщиках. В G1 существует процесс, называемый циклом пометки (marking cycle), который работает параллельно с основным приложением и составляет список живых объектов. За исключением последнего пункта, этот процесс выглядит уже знакомо для нас:

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

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

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

    Громадные регионы. С точки зрения JVM объекты которые превышают размер половины региона являются громадными. Особенности:

    Громадные объекты в силу небольшого размера регионов могут порождать проблемы с точки зрения STW.

    G1 выигрывает по времени STW, но расплатой является меньшая пропускная способность (около 90%, ср., например у Paraller ок. 99%) т.е. большие затраты ресурсов процессора.

    Bonus

    Вопрос: Расскажите почему именно два региона survival и зачем перекладывать объекты между ними?

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

    Вы просто заводите два указателя на начало новой области. Первый указатель (назовем его T) смещается вправо каждый раз, когда в новую область копируется объект, то есть он всегда указывает на первый свободный блок новой области. При этом на том месте старой области, где находился перемещаемый объект, мы делаем пометку о том, что он был перемещен, и там же оставляем его новый адрес. Первым делом перемещаем таким образом все руты из старой области в новую. И вот тут вступает в действие второй указатель (назовем его R). Он тоже начинает смещаться вправо по уже размещенным в новой области объектам. В каждом объекте он ищет ссылки на другие объекты и смотрит на то место в старом регионе, куда они указывают. Если там стоит метка о перемещении и новый адрес, то этот адрес используется для подмены. Если же там лежит объект, то он перемещается в новый регион, на его месте ставится метка и новый адрес, на который так же заменяется ссылка, по которой его нашли, при этом T опять смещается вправо. Как только R догонит T, окажется, что мы собрали все живые объекты в новой области, размещенные компактно, да еще и с корректно обновленными ссылками, а старый регион можем объявить пустым. Все быстро и просто.

    Источник

    Дюк, вынеси мусор! — Часть 1

    Что такое garbage collector java. Смотреть фото Что такое garbage collector java. Смотреть картинку Что такое garbage collector java. Картинка про Что такое garbage collector java. Фото Что такое garbage collector java

    Наверняка вы уже читали не один обзор механизмов сборки мусора в Java и настройка таких опций, как Xmx и Xms, превратилась для вас в обычную рутину. Но действительно ли вы в деталях понимаете, что происходит под капотом вашей виртуальной машины в тот момент, когда приходит время избавиться от ненужных объектов в памяти и ваш идеально оптимизированный метод начинает выполняться в несколько раз дольше положенного? И знаете ли вы, какие возможности предоставляют вам последние версии Java для оптимизации ответственной работы по сборке мусора, зачастую сильно влияющей на производительность вашего приложения?

    Попробуем в нескольких статьях пройти путь от описания базовых идей, лежащих в основе всех сборщиков мусора, до разбора алгоритмов работы и возможностей тонкой настройки различных сборщиков Java HotSpot VM (вы ведь знаете, что таких сборщиков четыре?). И самое главное, рассмотрим, каким образом эти знания можно использовать на практике.

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

    А оно мне надо?

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

    Разделяй и властвуй

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

    JVM разделяет используемую ею память на две области: куча (heap), в которой хранятся данные приложения, и не-куча (non-heap), в которой хранится код программы и другие вспомогательные данные.

    Если ваше приложение при работе самостоятельно не генерирует новые классы и не занимается постоянной подгрузкой / выгрузкой классов, то состояние non-heap в долгосрочной перспективе будет близким к статичному и мало поддающимся оптимизации. В связи с этим, механизмы функционирования области non-heap мы здесь рассматривать не будем, а сосредоточимся на той области, где наши усилия принесут наибольшую выгоду.

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

    Из поколения в поколение

    Что такое garbage collector java. Смотреть фото Что такое garbage collector java. Смотреть картинку Что такое garbage collector java. Картинка про Что такое garbage collector java. Фото Что такое garbage collector java

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

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

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

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

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

    Что такое garbage collector java. Смотреть фото Что такое garbage collector java. Смотреть картинку Что такое garbage collector java. Картинка про Что такое garbage collector java. Фото Что такое garbage collector java

    Вот тут и возникает идея разделения объектов на младшее поколение (young generation) и старшее поколение (old generation). В соответствии с этим разделением и процессы сборки мусора разделяются на малую сборку (minor GC), затрагивающую только младшее поколение, и полную сборку (full GC), которая может затрагивать оба поколения. Малые сборки выполняются достаточно часто и удаляют основную часть мертвых объектов. Полные сборки выполняются тогда, когда текущий объем выделенной программе памяти близок к исчерпанию и малой сборкой уже не обойтись.

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

    Вам быстро, дешево или качественно?

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

    Традиционно, при определении эффективности работы сборщика мусора учитываются следующие факторы:

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

    Memento Mori

    Господи, дай мне места для размещения того, что пока еще нужно,
    Дай мне смелости удалить то, что больше не пригодится,
    И дай мне мудрости, чтобы отличить одно от другого.
    — Молитва сборщиков мусора

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

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

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

    Но и просто сказать, что объект мертв и может быть удален только на основании того, что в программе не осталось ссылающихся на него (напрямую или опосредованно) еще используемых объектов, нельзя, так как разделение объектов на поколения вносит свои коррективы.

    Рассмотрим такую ситуацию: У нас есть молодой объект A и ссылающийся на него объект B, уже заслуживший место в старшем поколении. В какой-то момент времени оба этих объекта стали нам не нужны и мы обнулили все имеющиеся у нас ссылки на них. Очевидно, объект A можно было бы удалить в ближайшую малую сборку мусора, но для того, чтобы получить это знание, сборщику пришлось бы просмотреть всё старшее поколение и понять, что объект B ссылающийся на A, тоже является мусором, а следовательно их оба можно утилизировать. Но анализ старшего поколения не входит в план малой сборки, так как является относительно дорогой процедурой, поэтому объект А во время малой сборки будет считаться живым.

    Что такое garbage collector java. Смотреть фото Что такое garbage collector java. Смотреть картинку Что такое garbage collector java. Картинка про Что такое garbage collector java. Фото Что такое garbage collector java

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

    Кстати, время от момента, когда объект стал нам не нужен, до момента его фактического удаления из памяти называется проворством (promptness) и иногда рассматривается как дополнительный фактор оценки эффективности сборщика.

    Под микроскопом

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

    Внутренние инструменты

    Что касается внутренних инструментов мониторинга, то здесь мы можем либо попросить JVM выводить информацию о производимых сборках с различным уровнем детализации (в stdout или в лог-файл), либо самостоятельно обращаться к MXBean’ам, возвращающим информацию о состоянии памяти и о выполняемых сборках мусора, и обрабатывать ее как нам вздумается.

    В JVM HotSpot доступны следующие опции, управляющие выводом информации о сборках мусора (это основные опции, работающие для всех сборщиков):

    Включает режим логирования сборок мусора в stdout.
    Указывает имя файла, в который должна логироваться информация о сборках мусора. Имеет приоритет над -verbose:gc.
    Добавляет к информации о сборках временные метки (в виде количества секунд, прошедших с начала работы программы).
    Включает расширенный вывод информации о сборках мусора.
    При старте приложения выводит в stdout значения всех опций, заданных явно или установленных самой JVM. Сюда же попадают опции, относящиеся к сборке мусора. Часто бывает полезно посмотреть на присвоенные им значения.

    Если вы хотите собирать данные из своего приложения самостоятельно, то для этого можно использовать соответствующие MXBean’ы. Вот пример простого класса, который позволяет выводить текущее состояние различных регионов памяти, а также информацию о сборках мусора, его можно взять за основу, если хотите разработать свой собственный мониторинг:

    Внешние инструменты

    В природе существует огромное количество инструментов, позволяющих подключиться к процессу Java и в удобном виде получить информацию о состоянии памяти и процессах сборки мусора. Это и входящие в поставку JVM HotSpot утилиты VisualVM (с плагином VisualGC) и Java Mission Control и различные инструменты/плагины для IDE и отдельные программы вроде JProfiler или YourKit и еще много чего.

    Вы можете выбрать то, чем вам удобнее пользоваться, но как уже было сказано выше, обязательно проверьте, какое влияние оказывает ваш инструмент и его настройки на подопытное приложение. Вот пример того, как VisualVM влияет на поведение программы, весь исполняемый код которой состоит из приостановки выполнения основного потока:

    Что такое garbage collector java. Смотреть фото Что такое garbage collector java. Смотреть картинку Что такое garbage collector java. Картинка про Что такое garbage collector java. Фото Что такое garbage collector java

    Видите этот растущий график в верхней части? Это почти 8 МБ мусорных данных в минуту, привносимых мониторингом. Если вам нужно общее представление о том, как работает сборщик, либо если десяток мегабайт данных в минуту для вашей программы меньше допустимой погрешности измерений, то такое поведение инструменту можно простить. Но если вы проводите тонкую настройку и у вас каждый мегабайт на счету, то лучше выбрать что-нибудь менее прожорливое.

    В идеале, ваш инструмент должен отображать график использования памяти коматозной программой как-нибудь так:

    Что такое garbage collector java. Смотреть фото Что такое garbage collector java. Смотреть картинку Что такое garbage collector java. Картинка про Что такое garbage collector java. Фото Что такое garbage collector java

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

    А можно всех посмотреть?

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

    Как уже было сказано, описанные выше принципы сборки мусора являются общими для всех сборщиков. Но при этом между сборщиками существуют и заметные различия, проявляющиеся в ответах на следующие вопросы:

    Что такое garbage collector java. Смотреть фото Что такое garbage collector java. Смотреть картинку Что такое garbage collector java. Картинка про Что такое garbage collector java. Фото Что такое garbage collector java

    Java HotSpot VM предоставляет разработчикам на выбор четыре различных сборщика мусора:

    Serial (последовательный) — самый простой вариант для приложений с небольшим объемом данных и не требовательных к задержкам. Редко когда используется, но на слабых компьютерах может быть выбран виртуальной машиной в качестве сборщика по умолчанию.

    Parallel (параллельный) — наследует подходы к сборке от последовательного сборщика, но добавляет параллелизм в некоторые операции, а также возможности по автоматической подстройке под требуемые параметры производительности.

    Concurrent Mark Sweep (CMS) — нацелен на снижение максимальных задержек путем выполнения части работ по сборке мусора параллельно с основными потоками приложения. Подходит для работы с относительно большими объемами данных в памяти.

    Garbage-First (G1) — создан для постепенной замены CMS, особенно в серверных приложениях, работающих на многопроцессорных серверах и оперирующих большими объемами данных.

    В следующих статьях мы детально рассмотрим каждый из этих сборщиков, стараясь придерживаться общего плана: краткое описание, принципы работы, ситуации STW (это stop the world, если успели забыть), способы настройки, достоинства и недостатки. Получив эти знания, мы посмотрим, что с ними делать в реальной жизни.

    Источник

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *