在某些情况下,Go 会自动关闭文件描述吗?

时间:2021-03-19 17:52:44

标签: go

我试图检测 Go 打开的文件描述,但不要故意关闭。换句话说,我试图让我的代码“错误”,导致资源泄漏。

我的代码是

func hh(w http.ResponseWriter, r *http.Request) {
    f0, err := os.OpenFile("notes.txt", os.O_RDWR|os.O_CREATE, 0755)
    if err != nil {
        log.Fatal(err)
    }
    
    // I don't close file
    fmt.Println(io.ReadAll(f0))
}

func main() {
    http.HandleFunc("/req", hh)
    log.Fatal(http.ListenAndServe(":8080", nil))
}

我使用 shell 脚本文件 FCOUNT=`lsof -p $1 | grep -v " txt " | wc -l`;echo "PID: $1 $FCOUNT" | sort -nk3 打印出有多少文件描述属于这个 Go 程序。

无论我向此服务器 (curl http://localhost:8080/req) 发送多少个请求,我的 MacBook 上的数字仍然是 10。当然,我与 Activity Monitor 核对并得到相同的答案。

PS:我的第一个版本的代码实际上使用了 http.Get 并且没有关闭响应 Body。也有同样的情况。

我的环境:macOS Big Sur 11.2.3go version go1.16.2 darwin/amd64

有谁知道为什么文件描述编号在我认为应该泄漏时仍然保持不变?我的shell脚本错了吗?还是 Golang 里面有什么花样?

谢谢!

更新

问题是我正在检查名为 go 的进程而不是我的文件夹名称。 Go 真的给了我一个额外的 go 程序,看起来像一个守护进程,它不能显示 fd 细节。真实的程序清楚地显示了 fd 泄漏。尽管如此,我还是从有关 golang GC 的答案和评论中获得了一些知识。

我要结束这个问题。

2 个答案:

答案 0 :(得分:1)

在 Unix 中,打开的文件被垃圾收集器关闭:

https://golang.org/src/os/file_unix.go 第 186 行

答案 1 :(得分:1)

作为 Burak Serdar notes,打开的文件可能在 gc 期间被关闭。这意味着对主题行中提出的问题的答案——“在某些情况下 Go 会自动关闭文件描述吗?”——是“是”。但是在某些情况下这里做了很多繁重的工作。

垃圾收集实际发生的时间点通常很难预测(尽管您可以有意地自己调用 GC 代码)。终结器运行的时间点甚至更难预测,因为某些工作可能在单独的 goroutine 中完成。有关详细信息,请参阅 How to stop the golang gc and trigger it manually?,并注意 Go 的每个版本可能会更改有关 GC 内部的一些规则(尽管 GOGC 的操作非常稳定)。

相关问题