digital-garden/knowledge/dev/java/gc/Generational Collection.md

55 lines
5.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
aliases:
tags:
- зрелость/🌱
date: "[[2023-11-07]]"
zero-link:
- "[[../../../../garden/ru/meta/zero/00 Java разработка]]"
parents:
- "[[../../../../garden/ru/dev/java/gc/Garbage Collector]]"
linked:
---
Этот алгоритм основан на нескольких идеях.
- **Слабая гипотеза о поколениях:** Большинство объектов временные.
- **Сильная гипотеза о поколениях:** Чем старше объект, тем дольше он проживет.
- Поведение кешей с политикой [Least Recently Used](Least%20Recently%20Used.md) ей прямо противоречит
- Чем объект больше, тем больше шансов, что он нам будет нужен дольше по времени.
- Старые объекты редко ссылаются на молодые.
Поэтому куча часто делится на два "поколения" - молодое и старое. А сборщик мусора может использовать различные подходы для сборки в поколениях.
![](screen%201115.png)
![](Pasted%20image%2020231108091715.png)
- **Young Generation.** Здесь хранятся молодые объекты.
- **Eden Space.** Здесь выделяется память по новые объекты.
- **Survivor Space.** Сюда переносятся объекты, которые пережили несколько сборок мусора.
- **Old Generation.** Здесь хранятся долгоживущие объекты.
- Сборка мусора происходит реже
- [MetaSpace](Структура%20памяти%20Java.md#^MetaSpace)
- Сборка мусора здесь не производится
- С [java 8](Java%208%20LTS.md) называется MetaSpace, раньше называлось Pemanent Generation.
В общем случае новые объекты создаются в Eden, после чего какое-то время они находятся там. Если объекты пережили N сборок мусора, то сборщик мусора может принять решение о переносе объекта в Old Generation. Производительность сборки мусора в Young Generation напрямую зависит от количества живых объектов.
Конкретно в Hotspot, если объект большой (1+ mb) он может быть сразу помещен в Old Generation. А новые объекты создаются в области eden, если объект переживает сборку мусора, то он переносится в область s0, если переживает сборку в s0, переносится в s1, после чего переносится в Old Generation.
Если eden заполнен, то выполняется [minor](../../../../garden/ru/dev/java/gc/Garbage%20Collector.md#^minor) сборка мусора.
При сборке только в молодом поколении есть проблема: мы можем удалить объект в молодом поколении, на который ссылаются из старого поколения. В [Serial GC](Serial%20GC.md)/[Parallel GC](Parallel%20GC.md) для решения этой проблемы используют специальную структуру Card Table. При записи ссылки из старого поколения в молодое, в Card Table делается пометка. Эта пометка означает, что в такой-то области старого поколения может быть ссылка на молодое. То есть это не точное знание, а маркер, который говорит нам проверить какую-то область памяти на наличие ссылок.
![](Pasted%20image%2020231112093359.png)
В [G1](Garbage%20First.md) происходит примерно то же самое, но там помимо Card Table есть также Remembered Set. Remembered Set асинхронно строится по Card Table. Это позволяет нам собирать регионы отдельно.
![](Pasted%20image%2020231112093726.png)
Однако это привело к большом оверхеду по памяти для хранения этого Remembered Set. И с каких-то версий G1 стал более похожим на традиционные сборщики: ссылки между молодыми поколениями перестали хранится, но из-за этого мы должны собирать сразу все молодое поколение, мы больше не можем собирать только часть молодого поколения.
![](Pasted%20image%2020231112094217.png)
В [Shenandoah GC](Shenandoah%20GC.md) вместо Card Table решили использовать Matrix. Это грубый Card Table, но для каждого региона. Размер Matrix зависит от количества регионов.
![](Pasted%20image%2020231112094602.png)