3 ms·
Does Go's GC have any SLA about when an unreachable object must be garbage collected? If not, this is risky: 1. Will finalizers run on program crash? 2. Will
by tylerhou 4y ago
Does Go's GC have any SLA about when an unreachable object must be garbage collected? If not, this is risky:
1. Will finalizers run on program crash?
2. Will I run out of resources if the garbage collection doesn't run for sufficiently long time? (E.g. # of open file descriptors.)
3. Does the order of finalization matter?
Finalizers in Java were deprecated for the above reasons (and more). https://stackoverflow.com/a/56454348 https://stackoverflow.com/a/56454348
- TheDong 4y agoI agree it's not something that should be relied upon, nor is it elegant, I'm just pointing out that in the average case, failing to close a file is not a resource leak in the usual sense. It's not like forgetting to close a file descriptor in C. To answer each of your questions: 1. Generally no, but if your process exits then you definitely aren't leaking a file descriptor. The great finalizer in the linux kernel gets them then. 2. Yes absolutely, but that also isn't a leak. If you're opening a lot of files, you probably have to handle open failing as well anyway. 3. No order is guaranteed Most of this is documented on https://pkg.go.dev/runtime#SetFinalizer https://pkg.go.dev/runtime#SetFinalizer
- tylerhou 4y ago1. This can lead to programming errors if, e.g., a write is buffered in Golang and Close() flushes the buffer. Then you might not correctly write the file. (I know that if you really cared, you should use fsync, but lost writes could happen in e.g. logging where you don't want the overhead of fsync but you would also like to see all log output, especially on program crash.) 2. I think this is a bigger deal than you are making it out to be. If open fails, how would you handle it without just exiting? I can't see a way of forcing finalizers to run. If you're distributing your Go binary to users, you may not have permissions to increase the allowed number of file descriptors. So your program no longer functions correctly. Example: A program that processes files in parallel. At any given time it might have 2 * num_cores files open, well below the default descriptor limit on most systems. If I rely on finalizers running, then I might have to exit if the time to process each file is sufficiently short. There is no way to fix this without instructing the user to increase their fd limit. This is bad. Alternatively, if I explicitly closed files, I would never exit.