gpt4 book ai didi

go - gc 会在 Golang 中将数组设置为 nil 时收集对象吗?

转载 作者:IT王子 更新时间:2023-10-29 01:52:02 26 4
gpt4 key购买 nike

我有一个包含许多对象的数组。当我将数组设置为nil时,gc会收集数组持有的所有对象吗?

package main

import (
"time"
"runtime"
)

type B struct {
bb []int
}

func NewB() *B {
return new(B)
}

func main() {
var bs = make([]*B, 10)
for i:=0; i<10; i++ {
bs[i] = NewB()
bs[i].bb = make([]int, 1000000)
}

time.Sleep(time.Second)
println("begin gc")
//for i:=0; i<10; i++ {
// bs[i] = nil
//}
bs = nil
runtime.GC()
time.Sleep(time.Second*2)
runtime.GC()
time.Sleep(time.Second*2)
}

首先,我设置了bs = nil,两次gc信息都显示为76->76->76 MB,这意味着gc没有释放内存。然后,我在斜杠语句中添加 for 循环代码,第一个 gc 信息显示 76->76->0 MB,第二个 gc 信息显示 0->0->0 MB 。所以我很困惑,当我设置 bs = nil 时,没有指向所有对象的指针,为什么 gc 不释放对象?所有对象都应该显式设置为 nil 吗?

最佳答案

如果你编译时启用了逃逸分析,你会看到 bs 没有逃逸,所以分配在栈上,而不是堆上

go run -gcflags '-m -l' gc.go
# command-line-arguments
./gc.go:13:12: new(B) escapes to heap
./gc.go:20:18: make([]int, 1000000) escapes to heap
./gc.go:17:15: main make([]*B, 10) does not escape

因此,尽管您已将 bs 设为 nil,但 bs 指向的 slice 仍然被 gc 认为是活的,因为它在堆栈上。如果您将代码下推到它自己的 func 中,然后在它返回后进行 GC,您会看到 GC 确实回收了所有内存。

func main() {
alloc()
runtime.GC()
time.Sleep(time.Second * 2)
}

func alloc() {
var bs = make([]*B, 10)
for i := 0; i < 10; i++ {
bs[i] = NewB()
bs[i].bb = make([]int, 1000000)
}
time.Sleep(time.Second)
println("begin gc")
bs = nil
runtime.GC()
}



begin gc
gc 5 @1.003s 0%: 0.003+0.052+0.021 ms clock, 0.026+0/0.036/0.055+0.17 ms cpu, 76->76->76 MB, 137 MB goal, 8 P (forced)
gc 6 @1.003s 0%: 0.001+0.037+0.018 ms clock, 0.010+0/0.036/0.023+0.15 ms cpu, 76->76->0 MB, 152 MB goal, 8 P (forced)

关于go - gc 会在 Golang 中将数组设置为 nil 时收集对象吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50732829/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com