In the process of developing front-end application, like web application, "memory leak" means that a space created before cannot be used or collect any more until the browser is closed.
Though the browser has GC (Garbage Collection), but there is bug on this collection, which will lead to memory leak case.
Here we list some cases that will cause memory leak in JavaScript:
Event Listener
When a DOM has changed, if its event listener has not be removed, IE will not handle it for you and it causes memory leak.
In such kinds of cases, you can solve by remove the listner:
Or use event delegation(事件委託):
DOM or ActiveX Object Reference
In ECMAScript, reference between two DOM elements can be collected, if no other elements refer to them like:
var a = document.getElementById('xxx');
var b = document.getElementById('xx');
a.reference = b;
b.reference = a;
However, in IE, if you loop to refer to any DOM or ActiveX Object, GC won't collect and release these elements.
var a = document.getElementById('xxx');
a.reference = a;
Closure
Closures will sometimes cause memory leak by holding a variable.
function bindEvent() {
var obj = document.getElementById('xxx');
obj.onclick = function () {
};
}
For this situation, we can solve it by defining handling event outside the container:
function clickHandler() {
}
function bindEvent() {
var obj = document.getElementById('xxx');
obj.onclick = clickHandler;
}
Or directly release by deleting:
function bindEvent() {
var obj = document.getElementById('xxx');
obj.onclick = function () {
};
obj = null;
}
Delete loosely
Sometimes, if you delete an object loosely, it will result in memory leak:
var a = { p: { x: 1 } };
var b = a.p;
delete a.p;
console.log(b.x);
Therefore, when deleting an object, remember to delete recursively.
var a = { p: { x: 1 } };
var b = a.p;
function deleteObj(obj) {
if (_.isObject(obj)) {
delete obj;
for (var i in obj) {
deleteObj(i);
}
}
}
Boxing?
According to some documents, the following code will result in memory leak in IE, because IE will temporary create a String obj when accessing the property length, which will have a leak:
var s = 'abc';
console.log(s.length);
Therefore, before we access any property of a value object, we are recommended to convert them before:
var s = '123';
console.log(new String(s).length);
Illegal DOM Operations?
Some illegal DOM operations will result in memory leak in IE, like we call appendChild of a DOM element, which is not in the DOM tree.
Pollution of the global namespace
Undefined variable will be defined in the global name-space, which is another memory leak:
function foo() {
bar = 'this is a hidden global variable';
}
Actually:
function foo() {
window.bar = 'this is a hidden global variable';
}
More worse:
function foo() {
this.bar = 'potential global';
}
foo();
Therefore, we can use the strict mode to limit our code:
;