先贴代码:
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
)
func main() {
data := make(map[int32][]int32)
for i := 0; i < 1024; i++ {
msg := make([]int32, 1024 * 512, 1024 * 512)
msg[0] = 0 //访问一下内存, 触发从内核真正分配内存
data[int32(i)] = msg
}
fmt.Println(len(data))
if true {
sig := make(chan os.Signal, 1)
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
<-sig
}
}
编译:
GODEBUG=madvdontneed=1 GOOS=linux GOARCH=amd64 go build
如上,分配了 1024 个内存占用 2MB 的 slice,放入了 map 中,总共 2GB 内存占用。程序启动后分配完就一直阻塞着,大概 3 分钟后内存占用从 2GB 多降低到 70MB 左右,表现上看是之前分配的 slice 被 gc 了。但是 map 没有删除操作,也没有置为 nil,难道 golang 的 gc 机制就是这样,发现后续没有再使用这个 map 就直接 gc 了,尽管还没有离开这个 map 所在的作用域?
