I am thinking, when I create a System struct
, the builder system will cost much memory, but the result is simple, so if I return a address of result, will garbage know that it can collect the builder system memory?
How to test this?
I simulate the situation like this:
// Builder is used to build `System`, and it will cost much memory
type Builder struct {
aux [][]int
system *System
}
// System is the result of `Builder.build`, this is relatively simple
type System struct {
avg []float32
}
func NewSystem() *System {
builder := &Builder{system: &System{}}
builder.build()
return builder.system
}
func (builder *Builder) build() {
// mock initialize
maxCnt := 10000
builder.aux = make([][]int, maxCnt)
for i := range builder.aux {
builder.aux[i] = make([]int, maxCnt)
for j := range builder.aux[i] {
builder.aux[i][j] = rand.Intn(maxCnt)
}
}
builder.system.avg = make([]float32, len(builder.aux))
for i, col := range builder.aux {
var sum float32
for _, row := range col {
sum += float32(row)
}
builder.system.avg[i] = sum / float32(len(builder.aux))
}
}
func TestMem(t *testing.T) {
system := NewSystem()
// I want to know can garbage know that the memory cost by builder is able to be collected
fmt.Println("do many things with system")
fmt.Println(system.avg)
}
Yes, it will be garbage collected once there is enough memory pressure to trigger garbage collection (assuming it's even put on the heap; anything allocated to the stack doesn't need to be garbage collected, as the entire stack is deallocated when no longer in use). The garbage collector will deallocate anything with no remaining references. After your processing finishes, the only thing with a reference is the []float32
. If that were instead a slice of structs, and those structs had a pointer back to the parent object, that would prevent the parent being collected.