Will this javascript cause memory leak? - javascript

function outer(){
var a, b, c;
function inner1(){
...
}
function inner2(){
...
}
inner1();
inner2();
...
}
I want to keep the global namespace clean so I wrote above code. Inner functions are only used by code inside Outer. But after that I begin to thought if this will cause any memory problem. I'm not sure whether the inner functions are created beforehand or created each time the outer() is called? And will them cause memory leak?
Could someone help explain what will happen when outer() is called and when it returns? And please refer me if there are any good books or articles about javascript memory management. I always get confused by such problems. Thanks.

Not sure about first part but there is a similar question about the second part:
Do you know what may cause memory leaks in JavaScript?
How do I track and debug JavaScript memory leaks in Firefox?

The main problem that causes memory leaks in browsers with JavaScript is the fact, that the DOM and JS have two independet garbage collectors. If you begin to have references to DOM elements in your closure function and then again backreference to something inside the function you will face problems. Your structure is not leaking, but you want to do some more stuff and that maybe leaking.

In answer to your question about the creation of the inner functions: I believe your inner functions are created/defined every time you run outer(), and most JS interpreters should garbage-collect them after outer() runs, along with all the other variables in the function scope - unless outer() "exports" these inner functions outside of its own scope, e.g. assigning them as event handlers or including them in a return statement for later use.

Unless you put some other code inside - you should not worry about leaks in such simple closures. Modern javascript engines handle those very well.

Related

Do event handler function will leads to memory leak, which is referring to an outer scope element

Do event handler function will leads to memory leak, which is having element in outer scope
Ex:
function makeLableEditable(btnItem)
{
x.addDOMListener(btnItem.firstChild, 'onmousedown', function(){
btnItem.parentElement.setAttribute('draggable', false);
});
x.addDOMListener(btnItem.firstChild, 'onmouseup', function(){
btnItem.parentElement.setAttribute('draggable', true);
});
}
Do the above results in memory leak, as the event handler function referes to the outerscope html object (btnItem). Not reffering to the outerscope variable will solve the problem? (I still doubt)
Please help me to understand it.
Do the above results in memory leak, as the event handler function referes to the outerscope html object (btnItem).
It's not a leak, but yes, it keeps the "execution context" of the call to makeLableEditable in memory, and if btnItem refers to something that could later be garbage collected, it would keep it in memory. The functions you're creating there are "closures" over the context, and so they keep it around.
But it's not a leak. If the element that btnItem refers to is removed, or its firstChild element is removed, then the event handlers no longer have anything referencing them, and so they become eligible for GC — whereupon, anything they're keeping in memory is eligible for GC.
There were issues with Internet Explorer not successfully cleaning things up in some situations, but I don't think this would have triggered the problem, and in any case I believe IE9+ handle those situations correctly.
Not reffering to the outerscope variable will solve the problem?
In theory, it doesn't matter whether those functions refer to btnItem or not, they keep the execution context in memory.
In practice, JavaScript engines are allowed to optimize things as long as the optimization doesn't have observable side-effects other than reduced memory consumption and such. And so modern engines are smart about "optimizing" the closure and not keeping things around unnecessarily. They aren't perfect about it, but as long as your code isn't using eval or new Function (and your code isn't), the engine can usually optimize simple cases.

Nested helper functions and performance

Nested helper functions can be useful for making your code more understandable. Google even recommends using nested functions in their style guide. I'm wondering about the instantiation of these nested functions and performance. For example,
work(1);
work(2);
function work(a) {
// do some stuff
log();
// do some more stuff
function log() {
console.log(a);
}
}
work is instantiated once, but is log instantiated twice?
If log is instantiated every time work is executed, would it generally be recommended not to nest functions? Instead, write code like the following
work(1);
work(2);
function work(a) {
// do some stuff
log(a);
// do some more stuff
}
function log(a) {
console.log(a);
}
These examples are overly trivial and the question is more about the general case.
work is instantiated once, but is log instantiated twice?
Yes, on each call to work.
would it generally be recommended not to nest functions?
Why not? I presume you're hinting at performance issues.
Whether a practice is good or bad depends on your reasons for using it. In the case of simple helpers, it's good to keep them local because it means you can make them suitable just for your special case and not worry about the extra cruft of a general function. E.g. to pad a number with a leading zero:
function pad(n) {
return (n<10? '0' : '') + n;
}
works very well as a helper where n is expected to always be in the range 0 to 99, but as a general function is missing a lot of features (dealing with non–number n, -ve numbers, etc.).
If you are concerned about performance, you can always use a closure so the helper is only instantiated once:
var work = (function() {
function log() {
console.log(a);
}
return function (a) {
// do some stuff
log();
// do some more stuff
};
}());
Which can also make sense where log is used by more than one function within the closure.
Note that for a single case, this is very much a micro optimisation and not likely to deliver any noticeable difference in performance.
Nested function-objects are instantiated and added to the LexicalEnvironment created when an enclosing function is run. Each of these nested functions will also have a [[Scope]] property created on them. In addition when a nested function is run, a new LexicalEnvironment object will be created and the [[Scope]] copied to its outer property.
When the enclosing function completes, then the nested function-object and its associated memory will be eligible for garbage collection.
This process will repeat for every call to the outer function.
Contrast this with your second implementation, where the function-object need only be created once; likewise its garbage collection.
If this is a "hot" function (i.e. called many times) then the second implementation is infinitely preferable.
RobG is right. Performance us affected by instantiating functions for each work thread. Whether it is a noticeable problem or not really comes down to how many simultaneous active working threads you have, as this affects memory consumption as well as execution speed.
If performance is a big issue on your application (e.g. a complex, heavy function) and you only want to use the function in one place, closures are the way to go.
If the function you're calling from "work" is to be used from several parts of your code, it's better to keep them separate instead of nesting them. This makes to keep the code updated simpler (as you only update it in one place).
Most JS engines parse code only once (even for nested functions) so the work involved in instantiating functions is not a big issue.
Memory usage, on the other side, can be an issue if you have many nesting levels as well as several simultaneous threads or event listeners, so nesting should be managed carefully in these cases (on large-scale applications).
Yes. Instantiation occurs each time you invoke the nested functions. Instantiating functions does use CPU time but it's not as important as parsing.
So, for the general case (not the case now that you mention that your functions will be invoked many times per second), parsing time is more relevant than instantiation.
In this case, nesting functions will use a lot of memory and CPU time,CSO it's best to use RobG's solution (closures), where functions are instantiated once and they are simply called, causing less memory usage.
If you want more optimized code in this critical piece of code, you should try to use as few functions as possible as this will work faster, albeit at the expense of losing code readability and maintainability.

Break the encapsulation of immediately executed anonymous functions?

A common Javascript pattern is:
(function() {
var localScopedValue = "foobar";
// code... functions...
}());
The self-executing or immediately executed anonymous function creates a scope for everything inside it to prevent pollution of the global scope, and it also theoretically prevents anyone from getting references to either the function object or anything defined inside it from an outside script, browser console, etc. That's the idea, anyway.
However, Javascript being a dynamic language with reflection, etc., I am wondering if there is any way -- no matter how hackish (but not editing any existing code) -- of getting references to locals that are not deliberately exposed from Javascript code.
Reason: pure curiosity / breaking things.
Adding: Things I'm looking at include Function.caller and event listeners, basically anything where items inside the IIFE are known to call/hook out, but I can't put together the complete package.
JS doesn't have "real" reflection - all it has is the ability to access the properties of an object using a variable as a key with myObject[myVar] syntax instead of myObject.myProperty.
This therefore provides no access to lexically scoped private variables.

Does a for loop add another object to the scope chain in Javascript?

I watched this: http://www.youtube.com/watch?v=mHtdZgou0qU yesterday, and I've been thinking about how to improve my javascript. I'm trying to keep everything he said in mind when re-writing an animation that looked really choppy in firefox.
One of the things I'm wondering is if for loops add on to the scope chain. Zakas talked a lot about how closures add on to the scope chain, and accessing variables outside of the local scope tends to take longer. With a for loop, since you can declare a variable in the first statement, does this mean that it's adding another scope to the chain? I would assume not, because Zakas also said there is NO difference between do-while, while, and for loops, but it still seems like it would.
Part of the reason I ask is because I often see, in JS libraries, code like:
function foo(){
var x=window.bar,
i=0,
len=x.length;
for(;i<len;i++){
//
}
}
If for loops did add another object onto the chain, then this would be very inefficient code, because all the operations inside the loop (assuming they use i) would be accessing an out-of-scope variable.
Again, if I were asked to bet on it, I would say that they don't, but why then wouldn't the variables used be accessible outside of the loop?
JavaScript does not have block scope and it has variable hoisting, so any variables that appear to be defined in a for loop are not actually defined there.
The reason you see code like provided in your example is because of the hoisting behaviour. The code's author knows about variable hoisting so has declared all the variables for the scope at the start, so it's clear what JavaScript is doing.

Memory leaks in JavaScript: What are they, how to spot them, how to create them

I've just been helping out with some interviews for a new developer and JavaScript is a major part of my role and the role we're recruiting for. To be honest the candidate wasn't that good and he didn't really understand JavaScript however in the interview he confused JavaScript with C# and started to discuss memory leaks in JS. I wanted to intervene however it was at that point I realised how little I know about memory leaks in JS apart from the fact they use up lots of memory and slow things down.
When thinking about it during the interview the only thing I can remember is OReilly's Def Guide (think it was the fourth edition) mentioning Mark and Sweep Garbage Collections. But that has been fading ever since I read that and I can't really expand on that. I've found very little on this subject that's clear and concise (apart from an article by Crockford by that wasn’t that clear).
Can someone please sum up as simply as possible: What are memory leaks in JS, how we can spot them, how to create them - I've been writing JS for years and this has totally knocked my knowledge and confidence as I've never really thought about it!
Actually, a "true" memory leak should never be possible in a language that has an automatic garbage collector. So if there is a memory leak, its always an error in the underlaying engine (for instance, the problem of named function expressions in some IE's).
So, after we clarified that, it is still possible to gain a lot of memory with javascript and hold it without releasing. But that is not a true memory leak anyway. For instance, each function call creates a closure in ECMAscript. A lexical closure does, among other things, copy a reference to each parent context's data (activation and variable objects). So this needs some memory, especially if you're creating a lot of closures.
Another example from the Javascript DOM world: We are creating a dynamic image using new Image() and set the source to a big image. Now, we have a reference to the image and it cannot get garbage collected until all references are gone or unused (even if a good memory tool will correctly tell you that the memory was used for images and not for javascript).
But actually these are the only scenarios where you really can "leak" memory in this language. Again, it's not really leaking memory like a C malloc() where you forget to free() that section again. Since there is no dynamic memory managment in ECMAscript this stuff is totally out of your range.
Closures tend to often be mentioned when talking about leaking memory in JS. Example here:
http://www.javascriptkit.com/javatutors/closuresleak/index2.shtml
var trolls = (function () {
var reallyBigObject = eatMemory();
// make closure (#1)
// store reallyBigObject in closure
(function () {
var lulz = reallyBigObject;
})();
// make another closure (#2)
return function () {
return 42;
};
})();
You would expect trolls to just be function () { return 42; } and you would expect the reallyBigObject to be removed and garbage collected.
It's not, because if a single closure (#1) references a variable in the outer scope. Then all closures (#2 aswell) reference that variable.
Just because you have a reference to #2 means you have a reference to reallyBigObject which won't be cleared until #2 is dead.
Now consider your average closure heavy architecture where you wrap everything in closures and nest them 10 deep. You can see how easy it is to hold references to objects.
Note the above details apply to v8. Any fully ES5 compliant browser would leak with
var trolls = (function () {
var reallyBigObject = eatMemory();
return function () {};
})();
Because every inner function must have a reference to every closure variable defined in the outer scope, as per ES5. Most browsers take shortcuts and optimize this in a way that is not noticable.
Javascript is implemented different through all browsers. But there is a standard which all browsers should follow: ECMAscript.
Consider that all modern languages implement its own versions of reference counting, so the best way to avoid memory leaks is referencing all unused variables to null.

Categories

Resources