如果一个子类正在使用,是否会对父类进行垃圾回收?

huangapple go评论148阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2017年6月6日 16:21:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/44384864.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定