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

144 lines
9.7 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:
- сборщик мусора
- GC
- сборка мусора
- сборки мусора
- сборщику мусора
tags:
- зрелость/🌿
date: "[[2023-11-06]]"
zero-link:
- "[[00 Java разработка]]"
parents:
linked:
---
В некоторых языках есть механизм автоматического и безопасного освобождения оперативной памяти, ранее выделенной объектам в программе. Влияние разработчика на этот процесс опосредованное, прямого управления нет. Этот механизм принято называть Garbage collector (GC).
> [!WARNING] Структура памяти в Java
> Перед изучением данной темы необходимо понимать, как устроена память в Java.
Некоторые языки возлагают ответственность за управление памятью на разработчика, например C, C++, Rust. В таком случае разработчик должен сам, в коде, вызвать метод удаления объекта, чтобы освобождать память. Если этого не делать, то можно получить [[утечку памяти]].
Наличие GC в языке можно сравнить с коробкой автомат в автомобиле: вы получаете удобство, но в какой-то степени теряете контроль.
Вы получаете следующие преимущества:
- Ускорение разработки.
- Защита от утечек памяти.
B следующие недостатки:
- Потребление дополнительных вычислительных ресурсов.
- Утечки памяти :)
- [StopTheWorld](StopTheWorld.md)
> [!NOTE]- Шуточная молитва сборщиков мусора
> Дай мне места для размещения того, что пока еще нужно. Дай мне смелости удалить то, что больше не пригодится. И дай мне мудрости, чтобы отличить одно от другого.
## Производительность GC
Вам быстро, дешево или качественно?
- **Throughput.** Объем вычислительных ресурсов CPU, затрачиваемых на работу GC.
- **Предсказуемость.** На какое время прерывается работа приложения.
- **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
## Дополнительные материалы
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