Самая популярная статья на хабре, которая подробно объясняет как все устроено под капотом (но сложновато читается, как минимум для меня) https://habr.com/ru/companies/avito/articles/753244/ Ну и конечно оф.документация (но опять таки я плохо знаю иглиш, мне было тяжело читать) https://tip.golang.org/doc/gc-guide есть еше статья на хабре про gc https://habr.com/ru/articles/742402/ Если покопаться, то можно еще полезные статьи найти как можно пооптимизировать приложение и как gc и runtime в этом участвуют.
В моей статье не рассказывается подробно как все устроено под капотом, здесь цель была, чтобы было легко понять сам принцип работы новичку или человеку, который переходит на го
Привет! Спасибо за вопрос 🙌 Если коротко — да, при работе с интерфейсами часто происходит выделение в куче, и это даёт дополнительную нагрузку на сборщик мусора (GC). А теперь подробнее:
Когда ты присваиваешь значение переменной интерфейсного типа, например:
var x interface{} = 123
Go "упаковывает" значение внутрь интерфейсной структуры, в которой хранятся:
указатель на само значение,
и указатель на "тип" (таблицу методов и прочую инфу).
Если само значение изначально лежало на стеке, но ты передаёшь его как interface{}, Go переместит его в кучу — на случай, если интерфейс переживёт текущую функцию. Это называется escape to heap.
func makeIt() interface{} {
x := 42
return x // x убегает в кучу!
}
Хотя x — просто int, Go не уверен, насколько долго будет жить interface{}, поэтому играет безопасно — делает аллокацию в куче.
Вот откуда берутся "лишние объекты" — это такие вот маленькие аллокации, которых можно было бы избежать, если бы использовали конкретный тип вместо интерфейса. Хочешь убедиться? Скомпилируй этот код с анализом побега:
go build -gcflags="-m" main.go
И ты увидишь:
./main.go:9:9: x escapes to heap
Так что совет "избегайте интерфейсов без необходимости" — это не про стиль кода, а вполне практичная вещь: меньше аллокаций = меньше работы для GC = быстрее программа.
Самая популярная статья на хабре, которая подробно объясняет как все устроено под капотом (но сложновато читается, как минимум для меня)
https://habr.com/ru/companies/avito/articles/753244/
Ну и конечно оф.документация (но опять таки я плохо знаю иглиш, мне было тяжело читать)
https://tip.golang.org/doc/gc-guide
есть еше статья на хабре про gc
https://habr.com/ru/articles/742402/
Если покопаться, то можно еще полезные статьи найти как можно пооптимизировать приложение и как gc и runtime в этом участвуют.
В моей статье не рассказывается подробно как все устроено под капотом, здесь цель была, чтобы было легко понять сам принцип работы новичку или человеку, который переходит на го
ИИ помог сформулировать мои мысли, чтобы было понятно другому, не вижу в этом ничего плохого 😉
В любом случае благодарен любому комментарию
Привет! Спасибо за вопрос 🙌
Если коротко — да, при работе с интерфейсами часто происходит выделение в куче, и это даёт дополнительную нагрузку на сборщик мусора (GC). А теперь подробнее:
Когда ты присваиваешь значение переменной интерфейсного типа, например:
Go "упаковывает" значение внутрь интерфейсной структуры, в которой хранятся:
указатель на само значение,
и указатель на "тип" (таблицу методов и прочую инфу).
Если само значение изначально лежало на стеке, но ты передаёшь его как
interface{}
, Go переместит его в кучу — на случай, если интерфейс переживёт текущую функцию. Это называется escape to heap.Хотя
x
— простоint
, Go не уверен, насколько долго будет житьinterface{}
, поэтому играет безопасно — делает аллокацию в куче.Вот откуда берутся "лишние объекты" — это такие вот маленькие аллокации, которых можно было бы избежать, если бы использовали конкретный тип вместо интерфейса.
Хочешь убедиться? Скомпилируй этот код с анализом побега:
И ты увидишь:
Так что совет "избегайте интерфейсов без необходимости" — это не про стиль кода, а вполне практичная вещь: меньше аллокаций = меньше работы для GC = быстрее программа.
Надеюсь, помог