Close() 调用和垃圾收集器

Close() invocations and the garbage collector

在 Go 中,使用网络连接等资源的接口通常有一个 Close() 方法来处理这些资源。

现在我想知道如果实现接口的关联结构在没有调用 Close 的情况下被垃圾回收会发生什么。 OS 会保持网络连接/文件描述符/任何打开状态吗?垃圾收集器会做某事还是会阻止它接触该结构?

conn, _ := net.DialTCP(network, laddr, raddr)
// do stuff, then
conn = nil
// forgot to invoke `Close()`!!
// what happens now?

Os 将保留非关闭连接的文件描述符,一旦程序退出将被释放。

此类可关闭资源的终结器可能设置为 runtime.SetFinalizer, for example the netFD of TCPListener:

runtime.SetFinalizer(fd, (*netFD).Close)

这不应该是省略调用 Close() 以释放资源的原因,也因为无法保证终结器将被调用或何时:

The finalizer is scheduled to run at some arbitrary time after the program can no longer reach the object to which obj points. There is no guarantee that finalizers will run before a program exits, so typically they are useful only for releasing non-memory resources associated with an object during a long-running program.

调用 Close() 以确保资源已释放。

相关:

  • Which objects are finalized in Go by default and what are some of the pitfalls of it?