digital-garden/dev/java/gc/Garbage Collector.md

173 lines
11 KiB
Markdown
Raw Normal View History

2024-09-02 08:40:46 +03:00
---
aliases:
- сборщик мусора
- GC
- сборка мусора
- сборки мусора
- сборщику мусора
tags:
2024-09-04 20:02:42 +03:00
- maturity/🌿
2024-09-02 08:40:46 +03:00
zero-link:
- "[[../../../meta/zero/00 Java разработка|00 Java разработка]]"
parents:
- "[[../../../../knowledge/dev/java/Устройство Java|Устройство Java]]"
2024-09-02 08:40:46 +03:00
linked:
date: 2023-11-06
---
В некоторых языках есть механизм автоматического и безопасного освобождения оперативной памяти, ранее выделенной объектам в программе. Влияние разработчика на этот процесс опосредованное, прямого управления нет. Этот механизм принято называть Garbage collector (GC).
> [!WARNING] Структура памяти в Java
> Перед изучением данной темы необходимо понимать, как устроена память в Java.
Некоторые языки возлагают ответственность за управление памятью на разработчика, например C, C++, Rust. В таком случае разработчик должен сам, в коде, вызвать метод удаления объекта, чтобы освобождать память. Если этого не делать, то можно получить [[утечку памяти]].
Наличие GC в языке можно сравнить с коробкой автомат в автомобиле: вы получаете удобство, но в какой-то степени теряете контроль.
Вы получаете следующие преимущества:
- Ускорение разработки.
- Защита от утечек памяти.
B следующие недостатки:
- Потребление дополнительных вычислительных ресурсов.
- Утечки памяти :)
- [StopTheWorld](StopTheWorld.md)
> [!NOTE]- Шуточная молитва сборщиков мусора
> Дай мне места для размещения того, что пока еще нужно. Дай мне смелости удалить то, что больше не пригодится. И дай мне мудрости, чтобы отличить одно от другого.
## Производительность GC
Вам быстро, дешево или качественно?
- [[../../architecture/Throughput|Throughput]]. Объем вычислительных ресурсов CPU, затрачиваемых на работу GC.
2024-09-02 08:40:46 +03:00
- **Предсказуемость.** На какое время прерывается работа приложения.
- **Footprint.** Объем используемой памяти.
## Работа GC
Глобально у GC есть всего 2 задачи:
- Найти мусор. То есть понять, что объект больше не будет использоваться.
- И собрать мусор. Уничтожить такие объекты, чтобы на их месте можно было алоцировать новые.
> [!NOTE]
> В процессе своей работы GC не потребляет память в [[Heap]]
### Алгоритмы поиска мусора
#### Reference Counting
Этот алгоритм подсчитывает количество ссылок на каждый объект. Когда счетчик ссылок достигает нуля, объект считается недоступным.
Есть довольно много ситуаций, когда данный способ не работает. Например, циклический граф, где объекты ссылаются друг на друга, но они все являются мусором.
#### Tracing
Подсчет ссылок. Это наиболее распространенный алгоритм маркировки. Он начинается с изначально достижимых, "корневых" (GC Root), объектов и отслеживает все объекты, доступные от этих корней.
> [!QUESTION] Что может быть выбрано в качестве GC Root?
> Локальные переменные и статические переменные в Main классе и main методе, поток, который выполняет main, статические переменные, ссылки из JNI.
^gcroot
### Подходы к сбору мусора
- [StopTheWorld](StopTheWorld.md)
- [Copy Collector](Copy%20Collector.md)
- [Mark and Sweep](Mark%20and%20Sweep.md)
- [Mark and Compact](Mark%20and%20Compact.md)
- [Generational Collection](Generational%20Collection.md)
- [Incremental Collection](Incremental%20Collection.md)
- [Parallel Collection](Parallel%20Collection.md)
- [Concurrent Collection](Concurrent%20Collection.md)
### Потоки GC
#### Search thread
- Отдельный поток, который занимается поиском мусора и подает сигнал для запуска сборки.
- Как правило он один и работает параллельно с основной программой.
#### GC thread
- Отдельный поток, который занимается сборкой мусора.
- Таких потоков может быть много.
- Имеет несколько причин для старта.
- Может быть причиной StopTheWorld
### Причины старта GC
Главные:
- **Allocation Failure.** JVM попыталась выделить область памяти под новый объект, но памяти не хватило
- **GC Locker.** Кто-то подал сигнал на уборку.
Остальные:
- **Adaptive Size Ergonomics.**
- **Allocation Profiler.** Профайлер оказывает влияние на сборку мусора искажая показатели.
- **Heap Inspection.**
- **Heap Dump.**
- **No GC.** Если сборка мусора еще не запускалась или проходила давольно давно.
- **Last Ditch Collection.**
- **Perm Generation Ful.**
- **Meradata GC Threshold.**
### Minor Collection
^minor
Если количество используемой Eden Space памяти превышает некоторый заданный объем, то GC может выполнить быструю (minor) сборку мусора. По сравнению с полной сборкой мусора, данный процесс занимает немного времени и затрагивает только область молодого поколения, - устаревшие объекты без ссылок удаляются, а выжившие перемещаются в Survivor Space.
### Full Collection
В отличии от minor сборок охватывает весь Heap и занимает больше времени.
### Сборщики
- [Epsilon GC](Epsilon%20GC.md). Не собирает мусор :)
- [Serial GC](Serial%20GC.md). Морально устарел, но подойдет для консольных приложений.
- [Parallel GC](Parallel%20GC.md). Подходит для всех остальных случаев.
- [Parallel Compacting Collector](Parallel%20Compacting%20Collector.md).
- [Concurrent Mark Sweep](Concurrent%20Mark%20Sweep.md). Минимизирует время простоя в приложениях с долгоживущими данными. Подходит для web-приложений.
- [Garbage First](Garbage%20First.md). Хорошо подходит для больших объемов памяти в сочетании с небольшими объектами.
- Ultra-low latency
- [ZGC](ZGC.md)
- [Shenandoah GC](Shenandoah%20GC.md)
По умолчанию обычно используется или [Serial](Serial%20GC.md) или [Parallel GC](Parallel%20GC.md).
![](Pasted%20image%2020231108140632.png)
## Как повлиять на сборку?
- Писать код с учетом особенностей работы GC. Неблагодарный труд.
- Использовать флаги JVM
Команда `System.gc()` носит рекомендательный характер. Разработчик рекомендует JVM запустить GC, но JVM может этого и не сделать.
## Мониторинг работы GC
Минимальные накладные расходы
Параметры VM
- `-XX:+PrintGCDetails -XX:+PrintGCTimeStamps`
- `-Xlog:gc` Показывает время [StopTheWorld](StopTheWorld.md).
- Стоит помнить про [Safe Point](Safe%20Point.md). Этот параметр показывает время без учета накладных расходов.
- `-Xlog:safepoint`. Показывает время с накладными расходами.
- `-Xloggc:<file>`
- `-XX:+PrintGcDateStamps`
- `-XX:+PrintHeapAtGC`
- `-XX:+PrintTenuringDistribution`
Анализ диагностического вывода:
- PrintGCStats
- GChisto
- VisualVM / VisualGC
***
## Мета информация
**Область**:: [[../../../meta/zero/00 Java разработка|00 Java разработка]]
**Родитель**:: [[../../../../../knowledge/dev/java/Устройство Java|Устройство Java]]
**Источник**::
**Автор**::
**Создана**:: [[2023-11-06]]
### Дополнительные материалы
2024-09-02 08:40:46 +03:00
1. [Сборка мусора в Java](https://www.youtube.com/watch?v=St6iBm4sHl8).
1. В общих чертах о сборке мусора.
2. [Алексей Шипилёв — Shenandoah](https://www.youtube.com/watch?v=kKigibHrV5I).
1. Подробно рассказаны алгоритмы маркировки и копирования объектов.
3. [Заметки Гусев Влад](Garbage%20Collection.docx)
4. Есть какая-то книга GC Handbook
### Дочерние заметки
2024-09-14 23:38:42 +03:00
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
<!-- SerializedQuery: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
- [[Concurrent Collection]]
- [[Concurrent Mark Sweep]]
- [[Copy Collector]]
- [[Epsilon GC]]
- [[Garbage First]]
- [[Generational Collection]]
- [[Incremental Collection]]
- [[Mark and Compact]]
- [[Mark and Sweep]]
- [[Parallel Collection]]
- [[Parallel Compacting Collector]]
- [[Parallel GC]]
- [[Serial GC]]
- [[Shenandoah GC]]
- [[StopTheWorld]]
- [[ZGC]]
<!-- SerializedQuery END -->