Do I need to manually clear uncommitted variables in the closure?

I read this article ( http://javascript.info/tutorial/memory-leaks#memory-leak-size ) about memory leaks that mention this as a memory leak:

function f() { var data = "Large piece of data"; function inner() { return "Foo"; } return inner; } 

The JavaScript interpreter has no idea which variables an internal function might need, so it holds everything. In every external LexicalEnvironment. I hope the new interpreters try to optimize it, but are not sure of their success.

The article suggests manually setting data = null manually before returning the internal function.

It's right? Or is this article out of date? (If it's out of date, can someone point me to a resource about current traps)

+6
source share
2 answers

Modern engines will not support unused variables in the external area.

Therefore, it doesn’t matter if you set data = null before returning the inner function, because the inner function does not depend on ("close") data .

If the inner function did depending on the data - perhaps it returns it - then setting data = null is definitely not what you want, because then, well, that would be null, instead of having its original value!

Assuming that the inner function really depends on data , then yes, as long as inner points to something, then the value of data should be saved. But what you say you want! How can you get something available without its availability?

Remember that at some point, the variable that holds the return value of f() will itself go out of scope. At this point, at least until f() is called again, data will be garbage collected.

The general rule is that you don’t need to worry about memory and leak using JavaScript. This is the whole point of GC. The garbage collector does an excellent job of identifying what is needed and what is not needed, and preserving the former and the garbage collecting the latter.

You can consider the following example:

 function foo() { var x = 1; return function() { debugger; return 1; }; } function bar() { var x = 1; return function() { debugger; return x; }; } foo()(); bar()(); 

And look at its execution in the devtools Chrome Variables window. When the debugger stops in the internal function foo , note that x not present as a local variable or as a closure. For all practical purposes, it does not exist.

When the debugger stops in the internal function bar , we see the variable x , because it must be saved in order to be available for return.

It's right? Or is this article out of date?

No, it is not, and yes, it is. The article is four years old, and it's a lifetime in the world of the Internet. I don’t know if jQuery can be leaked, but I would be surprised if that were the case, and if so, there is a fairly simple way to avoid them - do not use jQuery. The leaks mentioned by the author of the article related to DOM loops and event handlers are absent in modern browsers, which I mean IE10 (rather IE9) and higher. I would suggest finding a more relevant link if you really want to understand a memory leak. In fact, I suggest you basically stop worrying about memory leaks. They occur only in very specialized situations. It's hard to find a lot on this subject online these days for this exact reason. Here is one article I found: http://point.davidglasser.net/2013/06/27/surprising-javascript-memory-leak.html .

+5
source

Just in addition to @torazaburo an excellent answer, it is worth noting that the examples in this tutorial are not leaks. A leak is what happens when a program removes a link to something, but does not free up the memory it consumes.

The last time I remember that JS developers were really worried about a genuine leak when Internet Explorer (6 and 7, I think) used separate memory management for DOM and JS. Because of this, it was possible to associate the onclick event with the button, destroy the button, and still have the event handler in memory - forever (or until the browser crashed or was closed by the user). You could not call the handler or release it after the fact. He just sat on the table, occupying the room. Therefore, if you have a long-lasting webapp or web page that created and destroyed many DOM elements, you had to be super-diligent to always unleash events before destroying them.

I also ran into several unpleasant iOS leaks, but these were all bugs and (eventually) were fixed by Apple.

However, a good developer should consider resource management when writing code. Consider these two constructors:

 function F() { var data = "One megabyte of data"; this.inner = new function () { return data; } } var G = function () {}; G.prototype.data = "One megabyte of data"; G.prototype.inner = function () { return this.data; }; 

If you were to create a thousand instances of F , the browser would have to allocate additional gigabytes of memory for all these copies of the huge string. And every time you delete an instance, you may get some poison on the screen when the GC eventually restores this ram. On the other hand, if you made a thousand instances of G , a huge string will be created once and reused by each instance. This is a huge performance boost.

But the advantage of F is that the huge string is essentially private. No other code outside the constructor can directly access this line. Because of this, each instance of F can change this line as much as we would like, and you never have to worry about problems for other instances.

On the other hand, a huge line in G is where anyone can change. Other instances can change it, and any code that has the same scope as G can also be.

Thus, in this case, there is a trade-off between resource use and security.

+1
source

All Articles