Golang память переменные
Объясните пожалуйста момент с памятью, первый вариант потребляет 7МБ памяти, а второй 0,9МБ. Что происходит с переменной v, почему то мне казалось что первый вариант должен наоборот меньше потреблять.
1 вариант
package main
type comm struct {
Id int
Text string
}
func (c *comm) getText() string {
return c.Text
}
func (c *comm) getId() int {
return c.Id
}
func main() {
var i int
var v *comm
for{
i++
v = &comm{i, "Привет"}
println(v.getId())
}
}
2 вариант
func main() {
var i int
for{
i++
v: = &comm{i, "Привет"}
println(v.getId())
}
}
Ответы (1 шт):
В первом случае структуры создаются в куче (heap), а во втором - на стеке. Вот и разница.
То что попадает в кучу, живёт там пока не придёт уборщик мусора и в памяти некоторое время может находиться более одной структуры. А в стеке один раз выделяется нужный размер памяти и далее она переиспользуется для всех структур, которые вы создаёте в цикле for.
Чтобы посмотреть, где создалась переменная, можно воспользоваться escape анализом (escape analysis).
Для первого варианта он говорит, что ссылка утекает в кучу (&comm literal escapes to heap):
# go build -gcflags "-m" test.go
# command-line-arguments
.test.go:8:6: can inline (*comm).getText
.test.go:12:6: can inline (*comm).getId
.test.go:27:24: inlining call to (*comm).getId
.test.go:8:7: leaking param: c to result ~r0 level=1
.test.go:12:7: c does not escape
.test.go:25:13: &comm literal escapes to heap
А для второго, что ничего не утекает (&comm literal does not escape):
# go build -gcflags "-m" test.go
# command-line-arguments
.test.go:8:6: can inline (*comm).getText
.test.go:12:6: can inline (*comm).getId
.test.go:25:24: inlining call to (*comm).getId
.test.go:8:7: leaking param: c to result ~r0 level=1
.test.go:12:7: c does not escape
.test.go:23:14: &comm literal does not escape
Но, обратите внимание, что в FAQ есть такой вопрос:
How do I know whether a variable is allocated on the heap or the stack?
где они вообще не рекомендуют задаваться этим вопросом, т.к. всё должно работать достаточно быстро в любом случае.