6 ms·
Can someone dumb it down for me how the new runtime.AddCleanup is different from much-disliked finalizers in java?
by never_inline 2y ago
Can someone dumb it down for me how the new runtime.AddCleanup is different from much-disliked finalizers in java?
- deleted 2y ago[deleted]
- ameliaquining 2y agoThe most important difference is that runtime.AddCleanup doesn't pass a reference to the decedent object to the cleanup callback. This is a big deal, because it means that, once the callback is called, you know that the object is completely dead and will never be reachable by anything ever again. By contrast, if the callback receives a reference to the object as an argument, then it is only mostly dead, because it is still reachable through that reference. If the callback stores a copy of that reference elsewhere before it returns, then the object is no longer unreachable, and the garbage collection that triggered the callback has to be cancelled. This is called "object resurrection" and it can cause all kinds of horrible chaos, e.g., by allowing an object that's part of a reference cycle to be observed in a partially-cleaned-up state wherein its internal invariants might be violated. Writing code that correctly deals with the possibility of object resurrection is very difficult. By contrast, runtime.AddCleanup mostly works the way you'd expect. There is one footgun, which is that, if the object to be cleaned up is reachable from the cleanup callback, then this will prevent it from ever becoming eligible for garbage collection, it will live forever, and the cleanup callback will never run. You have to be careful not to let that happen. But the consequence of messing this up is merely a resource leak, which is generally much less bad than the kinds of state corruption that object resurrection can cause. Lots of programming languages with garbage collection went through the cycle of starting out with a finalization API that allowed object resurrection, realizing that this was a bad idea, and deprecating it or discouraging its use in favor of a new API that doesn't have this problem. E.g., Go now recommends runtime.AddCleanup over runtime.SetFinalizer, Java now recommends java.lang.ref.Cleaner over Object.finalize, and Python now recommends weakref.finalize over __del__. JavaScript was fortunate in that it didn't gain support for any kind of finalization until 2021, by which time the hazards of object resurrection were well-understood, so it only has the good API and not the dangerous one.
- pjmlp 2y agoSmall hint, JavaScript is in the process of getting a dispose like API, already at stage 3. https://github.com/tc39/proposal-explicit-resource-management https://github.com/tc39/proposal-explicit-resource-managemen...
- icar 2y agoGood read about this if you are using Typescript and want to start using it now (pun inteded): https://www.totaltypescript.com/typescript-5-2-new-keyword-using https://www.totaltypescript.com/typescript-5-2-new-keyword-u...
- bakkoting 2y agoNote that the new disposable protocol in JavaScript is unrelated to garbage collection; it's more like Go's `defer`. The grandparent is talking about JavaScript's somewhat older FinalizationRegistry.
- pjmlp 2y agoSure, just like in many other languages with automatic memory management.
- orloffm 2y agoAnd C# was heavy on `Finalize()`, but now is all about `using/Dispose()`.
- deleted 2y ago[deleted]
- pjmlp 2y agoThis is Go, yet add again, catching up to the lessons learned by the other programming language communities. As you point out, finalizers are no longer in good grace in Java, not even in .NET, but lets leave that for another thread. Hence why they are deprecated since Java 9, released in 2017, and a Cleaner queue should be used instead, or try-with-resources. https://docs.oracle.com/javase/9/docs/api/java/lang/Object.html#finalize https://docs.oracle.com/javase/9/docs/api/java/lang/Object.h... Basically runtime.AddCleanup() is the Go's version of java.lang.ref.Cleaner::register().
- pigeonhole123 2y agoIt would be better if they didn't learn from the others
- Cthulhu_ 2y agoCan you explain? Because if you don't learn from others you're cursed to repeat the same mistakes. I like to mention Java's generics implementation making up half the language spec and compiler.
- anacrolix 2y ago"We're special. Hmm, okay that didn't work". Every Go feature.