158 lines
10 KiB
Markdown
158 lines
10 KiB
Markdown
---
|
||
aliases:
|
||
- сборщик мусора
|
||
- GC
|
||
- сборка мусора
|
||
- сборки мусора
|
||
- сборщику мусора
|
||
tags:
|
||
- maturity/🌿
|
||
zero-link:
|
||
- "[[../../../meta/zero/00 Java разработка|00 Java разработка]]"
|
||
parents:
|
||
- "[[../../../../knowledge/dev/java/Устройство Java|Устройство Java]]"
|
||
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.
|
||
- **Предсказуемость.** На какое время прерывается работа приложения.
|
||
- **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]]
|
||
### Дополнительные материалы
|
||
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
|
||
### Дочерние заметки
|
||
```dataview
|
||
LIST
|
||
FROM [[]]
|
||
WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link)
|
||
``` |