147 lines
9.9 KiB
Markdown
147 lines
9.9 KiB
Markdown
|
---
|
|||
|
aliases:
|
|||
|
- сборщик мусора
|
|||
|
- GC
|
|||
|
- сборка мусора
|
|||
|
- сборки мусора
|
|||
|
- сборщику мусора
|
|||
|
tags:
|
|||
|
- зрелость/🌱
|
|||
|
date: "[[2023-11-06]]"
|
|||
|
zero-link:
|
|||
|
- "[[00 Java разработка]]"
|
|||
|
parents:
|
|||
|
linked:
|
|||
|
---
|
|||
|
Под мусором подразумеваются объекты, которые больше не используются в приложении.
|
|||
|
|
|||
|
Некоторые языки возлагают ответственность за управление памятью на разработчика, например C, C++, Rust. В таком случае разработчик должен сам, в коде, вызвать метод удаления объекта, чтобы освобождать память. Если этого не делать, то можно получить [[утечку памяти]].
|
|||
|
|
|||
|
В некоторых языках есть механизм автоматического и безопасного освобождения оперативной памяти, ранее выделенной объектам в программе. Влияние разработчика на этот процесс опосредованное, прямого управления нет. Этот механизм принято называть Garbage collector (GC).
|
|||
|
|
|||
|
Наличие GC в языке можно сравнить с коробкой автомат в автомобиле: вы получаете удобство, но в какой-то степени теряете контроль.
|
|||
|
|
|||
|
С GC Вы получаете следующие преимущества:
|
|||
|
- Ускорение разработки.
|
|||
|
- Защита от утечек памяти.
|
|||
|
|
|||
|
и следующие недостатки:
|
|||
|
- Потребление дополнительных вычислительных ресурсов.
|
|||
|
- Утечки памяти :)
|
|||
|
- [StopTheWorld](StopTheWorld.md) паузы
|
|||
|
|
|||
|
> [!WARNING] Структура памяти в Java
|
|||
|
> Перед изучением данной темы необходимо понимать, как устроена память в Java.
|
|||
|
|
|||
|
> [!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
|