интервьюер: Я до сих пор помню, когда вы в последний раз упомянули "кучу", когда говорили о структуре памяти JVM (рантайм-области данных), а потом сказали, что она разделена на несколько областей
интервьюер: Я чувствовал, что мне придется работать сверхурочно, если я продолжу говорить.
интервьюер:Я сегодня немного свободен, продолжим разговор о "куче"
Кандидат: Ну, как было сказано ранее, куча делится на «Новое поколение» и «Старое поколение», «Новое поколение» делится на области «Эдем» и «Выживший», а область «Выживший» делится на «От выжившего». и «Выжившему» «Область
Кандидат: Сейчас я хочу поговорить о механизме сборки мусора в Java.
интервьюер: Затем вы начинаете свое шоу
Кандидат: Когда мы используем Java, мы создаем много объектов, но мы не очищаем эти объекты «вручную».
Кандидат: И если вы используете язык C/C++, вам нужно освободить (выпустить) его, когда он закончится.
Кандидат: Тогда почему мы не освобождаем "мусор" вручную при написании Java? Причина очень проста, за нас это делает JVM (автоматическая сборка мусора)
интервьюер: Эм…
Кандидат: Мое личное определение мусора: пока объект больше не используется, мы считаем объект мусором, а пространство, занимаемое объектом, можно утилизировать.
интервьюер:Так как же узнать, что объект больше не используется?
Кандидат: Существует два широко используемых алгоритма: «метод подсчета ссылок» и «метод анализа достижимости».
Кандидат: Идея подсчета ссылок очень проста: +1, когда на объект ссылаются, но -1, если ссылка на объект не удалась. Когда счетчик равен 0, объект больше не упоминается и может быть переработан.
Кандидат: наиболее очевидный недостаток метода подсчета ссылок: если объект имеет циклические зависимости, невозможно определить, следует ли повторно использовать объект (A зависит от B, B зависит от A).
интервьюер: Эм…
Кандидат: Другой метод анализа достижимости: он начинает поиск вниз от «GC Roots», когда объект не имеет ссылки на «GC Roots», это означает, что объект недоступен и может быть переработан.
Кандидат: "GC Roots" - это набор ссылок, которые должны быть "активными". Начиная с «GC Root», программа может находить объекты, которые могут использоваться, по прямой или косвенной ссылке.
интервьюер:Все еще не понял, что вообще такое "GC Roots"? Вы говорите, что это набор активных ссылок, можете привести пример, это слишком абстрактно.
Кандидат: Например, разве мы в прошлый раз не говорили о стеке виртуальной машины в структуре памяти JVM, в стеке виртуальной машины нет фрейма стека, в фрейме стека нет локальной переменной? Локальные переменные не хранят ссылки.
Кандидат: Если кадр стека находится на вершине стека виртуальной машины, означает ли это, что кадр стека активен (другими словами, поток вызывается)
Кандидат: поскольку поток вызывается, является ли ссылка на объект, указывающая на «кучу» в кадре стека, «активной» ссылкой?
Кандидат: Таким образом, ссылка на объект в куче, на который указывает текущий активный кадр стека, может быть «GC Roots».
интервьюер: Эм…
Кандидат: Конечно, в качестве «GC Roots» можно использовать не только небольшой фрагмент выше.
Кандидат: Например, ссылка на статическую переменную класса — «GC Roots», объект, на который ссылается «собственный метод Java», — это также «GC Roots» и т. д.
Кандидат: Вернёмся к сути понимания: "GC Roots" это набор "ссылок" которые должны быть "активными".Пока нет прямой или косвенной ссылки на "GC Roots" это фигня
Кандидат: JVM использует «алгоритм анализа достижимости», чтобы определить, является ли объект мусором.
интервьюер:понял
Кандидат: первый шаг сборки мусора — «маркировка», пометка объектов, на которые не ссылается «GC Roots».
Кандидат: После маркировки мы можем выбрать «очистить» напрямую, если это не связано с «GC Roots», его можно убить.
Кандидат: Процесс очень простой и сырой, но есть и явные проблемы
Кандидат: Будет проблема "фрагментации памяти" при очистке напрямую: Возможно у меня 10М свободной памяти, но программа не может претендовать на 9М памяти (10М памяти - это после удаления мусора, а не непрерывно)
Кандидат: Тоже относительно просто и грубо решить проблему "фрагментации памяти. После "разметки" она напрямую не "очищается".
Кандидат: Я "копирую" "отмеченные" уцелевшие объекты в другое пространство.После копирования я сразу убиваю все оригинальное пространство! Таким образом, нет проблемы фрагментации памяти.
Кандидат: Минус такого подхода очевиден: утилизация памяти низкая, и новую область мне приходится копировать (перемещать)
интервьюер: Эм…
Кандидат: Есть еще "компромиссный" метод. Мне не обязательно иметь "большое полное пространство" для решения проблемы фрагментации памяти. Мне нужно только иметь возможность перемещаться в пределах "текущей области"
Кандидат: Переместить уцелевшие объекты в одну сторону, переместить мусор в одну сторону, потом удалить мусор вместе, не будет фрагментации памяти
Кандидат: Этот профессиональный термин называется «организация».
Кандидат: После стольких лет давайте вернём наше мышление в "кучу"
Кандидат: после исследований было показано, что у большинства объектов короткий жизненный цикл, и лишь небольшое количество объектов может выжить в течение длительного времени.
Кандидат: А потому что "сборка мусора" приведет к "остановке мира" (приложение перестанет получать доступ)
Кандидат: Должно быть понятно "остановить мир": при сборе мусора программа не может продолжать нормально работать в течение короткого промежутка времени. В противном случае, когда JVM восстанавливает, пользовательский поток будет продолжать выделять и изменять ссылку, как это делает JVM (:
Кандидат: чтобы максимально сократить продолжительность «остановить мир» и увеличить скорость выделения памяти, с которой может справиться параллельный сборщик мусора.
Кандидат: Во многих сборщиках мусора два типа объектов различаются с точки зрения «физического» или «логического». «молодое поколение». Район называют «Старостью».
Кандидат: Но не все "сборщики мусора" будут иметь их, но теперь мы все можем использовать онлайн JDK8 Сборщики мусора, используемые в JDK8 и ниже, имеют концепцию "генерации".
Кандидат: Итак, вы видите, что моя "куча" нарисована "молодым поколением" и "старым поколением"
Кандидат: Стоит отметить, что ZGC сборщика мусора, используемого старшей версией, не имеет понятия генерации (:
Кандидат: Я просто хочу объяснить текущую ситуацию, мы можем поговорить об этом, когда ZGC будет свободен.
интервьюер:Ладно
Кандидат: Упомянутый ранее процесс сборки мусора, по сути, соответствует нескольким "алгоритмам сборки мусора", а именно:
Кандидат: Алгоритм удаления меток, алгоритм копирования меток и алгоритм сортировки меток ["Отметить" "Очистить" "Копировать" "Упорядочить"]
Кандидат: после вышеупомянутого предзнаменования эти алгоритмы должны быть относительно просты для понимания.
Кандидат: После понимания «генерации» и «алгоритма сборки мусора» мы можем взглянуть на распространенные сборщики мусора в рабочей среде JDK8 и ниже.
Кандидат: Сборщики мусора "молодого поколения": Seria, Parallel Scavenge, ParNew
Кандидат: Сборщики мусора "старого поколения": Serial Old, Parallel Old, CMS
Кандидат: Видя, что есть много сборщиков мусора, это на самом деле очень легко понять. Serial — однопоточный, Parallel — многопоточный.
Кандидат: эти сборщики мусора фактически «реализуют» алгоритмы сборки мусора (алгоритмы копирования, очистки и очистки).
Кандидат: CMS — это относительно новый сборщик мусора «до JDK8», который характеризуется возможностью максимально сократить время «остановки мира». Разрешить одновременное выполнение пользовательских потоков и потоков GC во время сборки мусора!
Кандидат: Также можно обнаружить, что сборщики мусора "молодого поколения" используют "алгоритм маркированного копирования"
Кандидат: Таким образом, в разделе «память кучи» молодое поколение разделено на область Survivor (Survivor From и Survivor To), цель состоит в том, чтобы иметь полное пространство памяти для копирования (перемещения) сборщиком мусора.
Кандидат: и новый объект размещается в районе Эдема
Кандидат: Я перерисую схему "памяти кучи" ниже, потому что их размер имеет шкалу по умолчанию.
Кандидат: я уже нарисовал картинку, так что мне не нужно больше объяснять
интервьюер:Еще хочу спросить, то есть вновь созданные объекты вообще в "новом поколении", так когда же они войдут в "старое поколение"?
Кандидат: Ну думаю по простоте можно разделить на два случая:
Кандидат: 1. Если объект слишком большой, он сразу войдет в старость (объект очень большой при создании || Область выжившего не может хранить объект)
Кандидат: 2. Если объект слишком старый, его возраст будет повышаться до старости (каждый раз, когда происходит Minor GC, возраст уцелевшего объекта +1, а значение по умолчанию 15 будет повышаться до старости || Динамический определение возраста объекта может войти в старость)
интервьюер:Поскольку вы снова упомянули Minor GC, когда будет запущен Minor GC?
Кандидат: Minor GC срабатывает, когда в области Eden недостаточно места.
интервьюер: Minor GC - это GC "молодого поколения" в моем понимании Вы упоминали ранее "GC Roots"?
интервьюер:Тогда в GC «молодого поколения», начиная с GC Roots, не будет ли он также сканировать объекты «старого поколения»? Тогда это ... разве это не эквивалентно полному сканированию кучи?
Кандидат: В этой JVM тоже есть решение.
Кандидат: «Старый GC» (ниже G1) виртуальной машины HotSpot требует, чтобы вся куча GC находилась в непрерывном адресном пространстве.
Кандидат: Таким образом, будет разделительная линия (одна сторона — старое поколение, другая сторона — молодое поколение), поэтому вы можете использовать «адрес», чтобы определить, к какому поколению относится объект.
Кандидат: При выполнении Minor GC, начиная с GC Roots, если вы находите предметы в "старости", то не спускайтесь вниз (Minor GC не имеет интереса к области старости)
интервьюер:Но есть еще одна проблема, а что, если на объект «молодого поколения» ссылается «старое поколение»? (Объекты старого поколения содержат ссылки на объекты молодого поколения), в то время определенно невозможно перерабатывать объекты «молодого поколения»..
Кандидат: Под виртуальной машиной HotSpot есть «карточный стол», чтобы избежать глобального сканирования объектов «старости».
Кандидат: Каждая небольшая область «памяти кучи» образует «карточную страницу», а карточная таблица на самом деле является набором карточных страниц. Если вы считаете, что на странице карточки есть ссылка из разных поколений на существующий объект, пометьте страницу как «грязную страницу».
Кандидат: Зная «карточный стол», с ним будет легко обращаться. Каждый раз, когда вы выполняете Minor GC, вам нужно только перейти к «карточному столу», чтобы найти «грязные страницы», и добавить их в корень GC после их обнаружения, вместо того, чтобы обходить все объекты «старости».
интервьюер: Хмммм, ладно, почему бы нам не продолжить разговор о CMS?
Кандидат: С момента интервью прошел почти час, а я нарисовала столько картинок. в следующий раз? В следующий раз? немного устал
Резюме этой статьи:
- что такое мусор: пока объект больше не используется, это мусор
- Как судить это как мусор: Алгоритм анализа достижимости и алгоритм эталонного вычисления, JVM использует алгоритм анализа достижимости
- Что такое корни GC: GC Roots — это набор ссылок, которые должны быть активны. Ссылки, не связанные с GC Roots, являются мусором и могут быть переработаны.
- Общие алгоритмы сборки мусора: Пометить как «Очистить», «Пометить как копирование», «Пометить как упорядочить»
- Зачем нужно поколение: Большинство объектов умирают рано, и лишь немногие выживают долгое время. Память кучи будет физически или логически генерироваться, чтобы максимально сократить продолжительность «остановить мир» и улучшить скорость выделения памяти, с которой может справиться параллельный сборщик мусора.
- Minor GC: срабатывает, когда область Эдема заполнена, проходя вниз от корней GC, GC молодого поколения не заботится об объектах старого поколения.
- что такое карточный стол[Таблица карт]: пространство для времени (аналогично растровому изображению), которое позволяет избежать сканирования всех соответствий старого поколения, а затем плавно выполнить второстепенный GC (случай: объект старого поколения содержит ссылку на объект молодого поколения)
- Соотношение кучи памяти: молодое поколение занимает 1/3 кучи памяти, а старое поколение занимает 2/3 кучи памяти. Район Эдема составляет 8/10 молодого поколения, а район Выживших — 2/10 молодого поколения (1/10 станций «Откуда» и «Куда»).
Добро пожаловать в мой публичный аккаунт WeChat【Java3y】 Давайте поговорим о Java-интервью, продолжайте обновлять серию линейных интервьюеров!
Серия [Онлайн-интервьюер-Мобильный терминал]Продолжаем обновлять два раза в неделю!
【Онлайн-интервьюер-компьютер】СерияПродолжаем обновлять два раза в неделю!
Оригинал это не просто! ! Проси три! !