1

In Go, interfaces that use resources like network connections usually have a Close() method that disposes of these resources.

Now I wonder what would happen if the associated structs implementing the interface get garbage-collected without Close having been invoked. Will the OS keep the network connection / file descriptor / whatever open? Will the garbage collector do something or will something even prevent it from touching that struct?

I.e.

conn, _ := net.DialTCP(network, laddr, raddr)
// do stuff, then
conn = nil
// forgot to invoke `Close()`!!
// what happens now?
blackgreen
  • 34,072
  • 23
  • 111
  • 129
Marcus Ilgner
  • 6,935
  • 2
  • 30
  • 44

2 Answers2

5

Such closeable resources may have finalizers set with runtime.SetFinalizer, for example the netFD of TCPListener:

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

This should not be a reason for omitting to call Close() to free resources, also because there is no guarantee that the finalizer will be called or when:

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.

Call Close() to make sure the resources are freed.

Related:

blackgreen
  • 34,072
  • 23
  • 111
  • 129
  • 2
    Moreover, the garbage collector paces itself based on Go memory usage — not kernel resources. So if you _were_ to rely on the finalizer to close the connections, you could very well run out of file descriptors before the collector decides to run again. – bcmills Aug 04 '21 at 18:21
2

Os will keep the file descriptors for non-closed connections, which is going to be freed once the program exits.

Oleg Butuzov
  • 4,795
  • 2
  • 24
  • 33