英文:
Will garbage collect the parent class if one child is in use?
问题
我正在思考,当我创建一个System
结构体时,构建器系统会占用很多内存,但结果很简单,所以如果我返回一个结果的地址,垃圾回收机制会知道它可以回收构建器系统的内存吗?
如何测试这个问题?
我模拟了以下情况:
// Builder用于构建`System`,它会占用很多内存
type Builder struct {
aux [][]int
system *System
}
// System是`Builder.build`的结果,相对简单
type System struct {
avg []float32
}
func NewSystem() *System {
builder := &Builder{system: &System{}}
builder.build()
return builder.system
}
func (builder *Builder) build() {
// 模拟初始化
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()
// 我想知道垃圾回收机制是否能知道构建器占用的内存可以被回收
fmt.Println("do many things with system")
fmt.Println(system.avg)
}
英文:
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)
}
答案1
得分: 1
是的,一旦有足够的内存压力触发垃圾回收,它就会被垃圾回收。假设它被放在堆上;分配给栈的任何内容都不需要进行垃圾回收,因为当不再使用时,整个栈都会被释放。垃圾收集器将释放所有没有剩余引用的内容。在处理完成后,唯一有引用的是[]float32
。如果它是一个结构体切片,并且这些结构体有一个指向父对象的指针,那么父对象就不会被回收。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论