I was reviewing the slides in this presentation: http://slid.es/gruizdevilla/memory
and on one of the slides, this code is presented with the suggestion that it creates a memory leak:
var a = function () {
var smallStr = 'x',
largeStr = new Array(1000000).join('x');
return function (n) {
eval(''); //maintains reference to largeStr
return smallStr;
};
}();
Closures can be another source of memory leaks. Understand what references are retained in the closure.
And remember: eval is evil
Can someone explain the issue here?
This process of accessing outer function's variable by an inner function is called a closure. A memory leak occurs when a declared variable is automatically available to the inner nested function and resides in a memory despite it is not referenced in the inner nested function.
Only capture variables as unowned when you can be sure they will be in memory whenever the closure is run, not just because you don't want to work with an optional self . This will help you prevent memory leaks in Swift closures, leading to better app performance.
In general, a Java memory leak happens when an application unintentionally (due to logical errors in code) holds on to object references that are no longer required. These unintentional object references prevent the built-in Java garbage collection mechanism from freeing up the memory consumed by these objects.
In computer science, a memory leak is a leak of resources when computer software incorrectly manages memory allocation. A memory leak occurs when your web application assigns memory and keeps using it even though it is no longer needed.
If instead of returning a function that does
eval('');
you returned one that passes its argument
eval(n);
then someone could call a('largeStr')
to get the array, so the JavaScript interpreter cannot garbage collect the array.
Interpreters could realize that
eval('');
is equivalent to
;
but most are not smart enough to do that, so as soon as they see eval
they stop allowing GC of closed-over variables as long as the closure is reachable.
The memory leak arises when eval
can't effectively access closed-over variables because of the nature of its input:
eval('x' + (n-1));
Since 'x' + (n-1)
can't produce a string of JS that references largeStr
no input can lead to largeStr
being used but it is still pinned in memory.
To see the whole thing in action, play around with
var f = (function () {
var a = [,,,,,];
return function (x) { return eval(x); };
})();
alert(f('a.length'));
Okay let's consider what happens here;
var a = (function () { // `a` will be set to the return of this function
var smallStr = 'x',
largeStr = new Array(1000000).join('x');
return function (n) { // which is another function; creating a closure
eval('');
return smallStr;
};
}());
The inner function needs to be able to access all variables from the outer function, meaning as long as a reference to it exists, variables from the outer function can't be garbage collected and hence continue consuming memory after it has finished invoking and therefore may result in "memory leaks".
If you're dealing with large data like this and you're finished with it, set it to null
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With