Golang chapter 0200#408
Conversation
|
@korepanov смотрю реквест, не переживай! Также работаю над восстановлением доступа к мессенджеру. |
|
@korepanov в этом реквесте тоже нужно разрешить конфликты. |
Ты в закрытом реквесте писала, что изменения по тестам практики на пайплан уже на проде. Но на сайте все тот же тест, старый. Кроме того, помимо сообщений о результатах теста, сайт выдает это: Это сообщение возникает, если ничего не трогать в практике, а сразу отправить на проверку. Так должно быть? |
Разрешил. |
Ты нажимал на кнопку "сбросить решение"? |
Нажимал. |
| ## Старый сборщик мусора | ||
| ### Какую память очищает сборщик мусора | ||
|
|
||
| Прежде чем рассматривать сборщик мусора, поговорим о памяти, которую сборщик мусора **не** очищает. Сборщик мусора не очищает значения локальных переменных, которые не являются указателями. Такие переменные хранятся на **стеке** горутины. Компилятор Go сам может определить, когда их необходимо очистить. Для этого он генерирует соответствующие машинные инструкции. |
There was a problem hiding this comment.
Предложение с двумя отрицаниями тяжело читается.
|
|
||
| Прежде чем рассматривать сборщик мусора, поговорим о памяти, которую сборщик мусора **не** очищает. Сборщик мусора не очищает значения локальных переменных, которые не являются указателями. Такие переменные хранятся на **стеке** горутины. Компилятор Go сам может определить, когда их необходимо очистить. Для этого он генерирует соответствующие машинные инструкции. | ||
|
|
||
| Есть переменные, время жизни которых компилятор определить не способен. Скажем, возвращаемые из функции переменные: неизвестно, когда их нужно уничтожить. Объемный массив вообще не поместится в стек. Иногда мы и вовсе не знаем о том, сколько памяти нам потребуется. Например, для базового массива среза, начальный размер которого определяется переменной, а не константой. Память в таких ситуациях выделяется динамически. Все эти значения помещаются в **кучу**. Именно с ними работает сборщик мусора. |
There was a problem hiding this comment.
Про стек и кучу нужно дать ссылки на вики или другой достоверный ресурс.
|
|
||
| Прежде чем рассматривать сборщик мусора, поговорим о памяти, которую сборщик мусора **не** очищает. Сборщик мусора не очищает значения локальных переменных, которые не являются указателями. Такие переменные хранятся на **стеке** горутины. Компилятор Go сам может определить, когда их необходимо очистить. Для этого он генерирует соответствующие машинные инструкции. | ||
|
|
||
| Есть переменные, время жизни которых компилятор определить не способен. Скажем, возвращаемые из функции переменные: неизвестно, когда их нужно уничтожить. Объемный массив вообще не поместится в стек. Иногда мы и вовсе не знаем о том, сколько памяти нам потребуется. Например, для базового массива среза, начальный размер которого определяется переменной, а не константой. Память в таких ситуациях выделяется динамически. Все эти значения помещаются в **кучу**. Именно с ними работает сборщик мусора. |
There was a problem hiding this comment.
Для библиотеки времени выполнения (рантайма), кучи (хипа) и других определений в скобках дай английские названия.
|
|
||
| ### Цикл сборки мусора | ||
|
|
||
| Как мы уже поняли, сборщик мусора может работать в режиме пометки и режиме очистки памяти. Процессы пометки и очистки не могут быть выполнены параллельно. Пока не поймем, что на данный объект не ссылается ни один указатель, мы не можем очистить память. Кроме того, сборщик мусора бывает вообще не активен, когда для него нет никакой работы. Таким образом, сборщик мусора находится в одном из трех состояний: пометка, очистка и выключение. Непрерывный переход из одного состояние в другое называется **циклом сборки мусора**. |
There was a problem hiding this comment.
"Как мы уже поняли" - убери, пожалуйста.
| Есть переменные, время жизни которых компилятор определить не способен. Скажем, возвращаемые из функции переменные: неизвестно, когда их нужно уничтожить. Объемный массив вообще не поместится в стек. Иногда мы и вовсе не знаем о том, сколько памяти нам потребуется. Например, для базового массива среза, начальный размер которого определяется переменной, а не константой. Память в таких ситуациях выделяется динамически. Все эти значения помещаются в **кучу**. Именно с ними работает сборщик мусора. | ||
|
|
||
| ## Трассировка сборщика мусора | ||
| Разные сборщики мусора по-разному определяют память, которую необходимо высвободить. Например, часть из них ведут подсчет ссылок. Как только счетчик ссылок на некоторую область памяти становится равным нулю, память освобождается. |
There was a problem hiding this comment.
Так работает GC питона, да? Давай скажем про это.
|
|
||
| Затраченное процессорное время зависит от общего количества циклов сборщика мусора за заданный промежуток времени. Кроме того, чем чаще запускается сборщик мусора, тем меньше памяти он тратит. Однако тем больше мы расходуем процессорного времени. Как найти компромисс между тем и другим? За то, как часто запускать сборщик мусора, отвечает параметр **GOGC**. | ||
|
|
||
| ## GOGC |
There was a problem hiding this comment.
Весь раздел про GOGC совершенно непонятен.
GOGCопределяет компромисс между
Он определяет целевой размер кучи
GOGC— это целевое значение для роста кучи, выраженное в процентах
Три разных определения, и при этом совершенно непонятно, что это такое. Ни расшифровки Go Garbage Collector, ни ответов на вопросы, что это. Это параметр? Кто его задает? Если программист, то что, его в каждой программе нужно задавать?
Альтернативный вариант.
GOGC ( ... ) - это главный рычаг управления памятью в программе на Go. От него зависит, как часто будет запускаться сборищик мусора, чтобы очистить все лишнее.
GOGC - это глобальная конфигурационная переменная внутри рантайма. Она хранит целое число - процент. По умолчанию GOGC равен 100%. Разберем на примере, как это работает:
- Программа запустилась и оставила в памяти 10 Мб нужных данных.
- Сборщик мусора смотрит на GOGC=100 и считает: 10 Мб + 100% = 20 Мб.
- Программа работает дальше и копит новый мусор.
- Как только общая память дойдет до 20 МБ, включится сборщик и удалит лишнее.
Значение 100% подходит подавляющему большинству программ. Но в двух случаех может потребоваться изменить его:
- Для того, чтобы выжать максимум скорости, GOGC повышается до 200, 500 или даже 1000, чтобы сборщик включался реже.
- Для того, чтобы жестко контролировать расход памяти, GOGC занижается до 50 или даже 30. Это нужно, если программа работает в Docker-контейнере с ограниченной памятью или на слабом железе.
...Как-то так. А не два длинных абзаца, из которых ничего не понятно.
| GOMEMLIMIT=1024 go run cmd/main.go | ||
| ``` | ||
|
|
||
| Отметим одну важную деталь. Если выставить `GOGC=off` и начать постепенно уменьшать объем доступной памяти, то сборщик мусора будет по-прежнему срабатывать. Он будет включаться по мере достижения размера использованной памяти параметру `GOMEMLIMIT`. Когда объема доступной памяти станет совсем мало, сборщик мусора будет включен почти постоянно. Он будет пытаться поддерживать невыполнимый предел. Такая ситуация называется **«thrashing»**. Она особенно опасна, потому что приводит к зависанию программы. |
There was a problem hiding this comment.
Что будет, если программе потребуется памяти больше, чем выставленный лимит? OOM kill и вот это все.
|
|
||
| Идея сборщика мусора Green Tea состоит в том, чтобы отслеживать не объекты, а страницы с объектами. Нужно помечать не все объекты подряд, а те объекты, которые находятся на данной странице, а затем переходить к следующей. Вместо того, чтобы просто идти по указателям на объекты, мы перемещаемся по указателям внутри конкретной страницы. Сами же страницы выстраиваются в очередь. Такой прием обеспечивает хорошую совместимость с архитектурой процессора. Мы сканируем близкие друг к другу объекты с большей вероятностью. Таким образом, мы чаще используем кеш. Подробнее про алгоритм рассказано на [официальном сайте](https://go.dev/blog/greenteagc) языка. | ||
|
|
||
| ## Резюме |
There was a problem hiding this comment.
В главе не сказано явно про STW (Stop The World), когда программа тупо останавливается, хоть и на доли миллисекунды.
| const expNumber = 1000 | ||
| var mem [][]byte | ||
| for range expNumber { | ||
| const mb = 1024 * 1024 |
There was a problem hiding this comment.
А почему константа объявляется внутри цикла? Так запланировано?
| loadElapsed := time.Since(loadStart) | ||
| var m2 runtime.MemStats | ||
| runtime.ReadMemStats(&m2) | ||
| fmt.Printf("\nStatistics after the test:\n") |
There was a problem hiding this comment.
5 подряд идущих вызовов fmt.Printf(). Ты же можешь сам объяснить, почему так плохо?
Предлагаю здесь и вообще везде по курсу объединять их. Типа такого
fmt.Printf(`--- Case: %s ---
Alloc: %d KB
Sys: %d KB
`,
test.name,
(memAfter.Alloc-memBefore.Alloc)/1024,
(memAfter.Sys-memBefore.Sys)/1024,
)| 0 | ||
| ``` | ||
|
|
||
| ## Новый сборщик мусора Green Tea |
There was a problem hiding this comment.
Насколько я поняла с официального сайта, это экспериментальный сборщик. И он не будет работать, пока ты сам не выставишь во время сборки GOEXPERIMENT=greenteagc.
Об этом обязательно нужно сказать.
|
|
||
| Идея сборщика мусора Green Tea состоит в том, чтобы отслеживать не объекты, а страницы с объектами. Нужно помечать не все объекты подряд, а те объекты, которые находятся на данной странице, а затем переходить к следующей. Вместо того, чтобы просто идти по указателям на объекты, мы перемещаемся по указателям внутри конкретной страницы. Сами же страницы выстраиваются в очередь. Такой прием обеспечивает хорошую совместимость с архитектурой процессора. Мы сканируем близкие друг к другу объекты с большей вероятностью. Таким образом, мы чаще используем кеш. Подробнее про алгоритм рассказано на [официальном сайте](https://go.dev/blog/greenteagc) языка. | ||
|
|
||
| ## Резюме |
There was a problem hiding this comment.
Выполняется программа на Go
│ │ │
▼ ▼ ▼
┌───────────────────────┐
│ Создаются переменные │
│ Выделяется память │
└───────────────────────┘
│ │ │
──────┼───────┼───────┼───────── Нужна сборка мусора
│ │ │
▼ ▼ ▼
┌───────────────────────┐
│ STW │ ◄─── Сборщик мусора останавливает
│ │ все ваши функции
└───────────────────────┘
│ │ │
──────┼───────┼───────┼───────── Программа возобновляет работу
│ │ │
▼ ▼ ▼
┌───────────────────────┐
│ Работа программы + │ ◄─── Программа работает,
│ маркировка мусора │ сборщик мусора ищет мусор в фоне
└───────────────────────┘
No description provided.