Hacker News new | past | comments | ask | show | jobs | submit login

It's neat, but if I understand it correctly, if you forget to write the "using" keyword the code will still work just fine but the dispose will never be called, resulting in a memory leak. I don't suppose there is a way to mark a function as being un-callable unless you do so with "using"?



That situation already exists today, but is inconsistent: some things need .close() and others .dispose() and yet others .destroy() and then there's things like .end() and .reset() and .disconnect() and .revoke() and .unsubscribe(). All of those and more already exist in JS code today (just off the top of my head) with notes in library READMEs or other documentation to call them or possibly face resource leaks. The `using` keyword suggests a common name for these sorts of functions, [Symbol.dispose](), and provides lovely syntax sugar for try/catch/finally to make sure such things get called even in failure cases, and even provides suggested built-in objects DisposableStack and AsyncDisposableStack to help in managing multiple ones and transitioning older APIs like the many names I've seen, mentioned here.

Even better, right now lint tools have to individually case rules specific to each library given the variety of names, but lint tools can make a nice global rule for all objects implementing [Symbol.dispose]() (just as they can warn when a Promise is left unawaited).


Eslint will probably have a rule about it. As `call a function return promise without using the result` have a relevant rule today.

Probably it will block the pattern that `call a function that returns disposable object without using using keyword`...etc.


In C#, the garbage collector will eventually call the destructor that will dispose the object. It just won't happen deterministically with the code.

I assume there would be similar logic for JavaScript but I haven't looked at the specification.

It is not always a mistake to miss the using keyword -- if you're taking ownership of the object, then you will dispose of it manually (potentially in your own dispose method).


I'm not aware of a way to control the GC behavior of an object in JS. The memory will be freed, and that's all. If something else needed to be done, I don't think there's a way to do it. Happy to be proven wrong though.


You can kinda use a WeakMap to later detect if an object has been dereferenced, and thus run some sorta cleanup routine.


How? WeakMap (and WeakSet, more directly) can detect if an object has been collected only if you have a reference to pass to it. If you have reference to the object in a variable or data structure, it won't have been eligible for collection in the first place.


You can't use a WeakMap or a WeakSet, but you can use a WeakRef or a FinalizationRegistry.


I did not know about these things. Looks cool!


There's a conversation I had with Ron Buckton, the proposal champion, mainly on this specific issue. [1]

Short answer: Yes, Disposable can leak if you forget "using" it. And it will leak if the Disposable is not guarded by advanced GC mechanisms like the FinalizationRegistry.

Unlike C# where it's relatively easier to utilize its GC to dispose undisposed resources [2], properly utilizing FinalizationRegistry to do the same thing in JavaScript is not that simple. In response to our conversation, Ron is proposing adding the use of FinalizationRegistry as a best practice note [3], but only for native handles. It's mainly meant for JS engine developers.

Most JS developers wrapping anything inside a Disposable would not go through the complexity of integrating with FinalizationRegistry, thus cannot gain the same level of memory-safety, and will leak if not "using" it.

IMO this design will cause a lot of problems, misuses and abuses. But making JS to look more like C# is on Microsoft's agenda so they are probably not going to change anything.

[1]: https://github.com/tc39/proposal-explicit-resource-managemen...

[2]: https://stackoverflow.com/a/538238/1481095

[3]: https://github.com/tc39/proposal-explicit-resource-managemen...


No, but static code analysis could do a good job at catching this (at least it does in C#).


well maybe you want to explicitly free it later...


JavaScript is a garbage collected language, so no memory leak is possible.


Memory leaks may not be possible but resource leaks can be.

Many languages have tried to attach "disposers" to garbage collection events. The more common term in this case is "finalizer". As far as I know, no language has ever had a general-purpose, robust solution that works so well that it can just be used. Many have tried, and they all end up either deprecated, determined by the community to be a footgun, or backed down to some specialized use case (like picking up after file handles that are GC'd but the expected thing is still that normal user code closes them and this is explicitly pitched as an undesirable fallback, not the thing you should do).


No, there are some objects that need to be disposed explicitly.

For example, if you're using three.js, various WebGL resources need to be manually disposed: https://threejs.org/docs/index.html#manual/en/introduction/H...


Garbage collection doesn't prevent memory leaks. Nothing stops you from filling up a Map and never emptying it


It's not a leak if the memory is still referenced! A garbage-collected system can never leak memory.


The problem with that definition of "memory leak" is that it's not useful to programmers.

A more useful definition is memory that remains allocated unintentionally.


How is that more useful? According to your definition, languages have nothing to do with memory leaks, pro or contra.


I think programmers mainly care about memory leaks because of the potential negative consequences of using up too much memory -- programs crash or fail, or services frequently restart, or you have to provision additional costly server resources to keep things running well.

If your program continuously allocates memory that it doesn't free and doesn't serve a useful purpose, it doesn't really matter if it's, e.g., being referenced by some cache or just completely unreferenced -- it's still causing the same problem and has the same solution (that is, release the memory when you're done with it -- whether that's by calling "free" or clearing the reference, or whatever your memory management system has)


You’re being pedantic. “Memory leak” is colloquially used when you have data in memory which accumulates and isn’t actively being used by the system.


Memory allocated for the map is supposed to be freed when the variable goes out of scope.


Nope. It's freed when there's nothing referencing it any longer, at the next garbage collect.

Here are common pitfalls: https://auth0.com/blog/four-types-of-leaks-in-your-javascrip...




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: