直接回答:Go 里有 GC 不等于什么都不用管:os.File、net.Conn、http.Response.Body、sql.Rows、sql.DB 这些都必须显式 Close,否则会句柄泄漏,最终把进程拖死。

在 Go 语言中,有一些资源需要在使用完后手动释放,以避免资源泄漏和浪费,具体来说包括:

  • 文件句柄(*os.File):文件对象需要在使用完后调用Close()方法手动关闭,以避免因资源泄漏而导致系统文件句柄数量达到上限。
1
2
3
4
5
f, err := os.Open("file.txt")
if err != nil {
// 处理错误
}
defer f.Close()
  • 网络连接(net.Conn):网络连接需要在使用完后调用Close()方法手动关闭,以避免因连接过多而占用过多系统资源。
1
2
3
4
5
conn, err := net.Dial("tcp", "address")
if err != nil {
// 处理错误
}
defer conn.Close()
  • 通道(channel):当通道不再需要时,需要显式地将其关闭以避免其阻塞 goroutine。
  • 定时器(time.Timer):定时器需要手动停止(stop),否则可能会在 goroutine 关闭时导致死锁或泄漏。
1
2
timer := time.NewTimer(time.Second * 5)
defer timer.Stop()
  • SQL(database/sql.DB和database/sql.Tx):数据库连接需要在使用完后调用Close()方法手动关闭,以避免因连接过多而占用过多系统资源(如果有连接池的情况下,使用完后返回连接池就好了,不需要手动关闭)。
  • HTTP请求得到响应后,需要调用响应体的 Close() 方法来手动关闭所关联的数据流以释放相应的系统资源。
1
2
3
4
5
resp, err := http.Get("http://www.example.com/")
if err != nil {
// 处理错误
}
defer resp.Body.Close() // 在函数退出前关闭响应体

Go语言中大多数资源都会自动释放,但一些资源仍需要手动释放以确保程序的效率和稳定性。因此,要时刻谨记在使用完相关资源后要调用相应的释放方法。

这篇笔记整理自我自己的实践记录,如果做法有出入,或者你踩过别的坑,欢迎到留言板一起聊聊。

站内搜索

没有找到内容!