55 lines
5.4 KiB
Markdown
55 lines
5.4 KiB
Markdown
---
|
||
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) |