I have a Javascript class like below:
var MYCLASS = function(elem, data, op) {
var options = {};
var loopForEver = function() {
console.log('I cant stop me');
setTimeout(function() {
loopForEver();
}, 1000);
}
this.init = function() {
loopForEver();
}
}
when I instantiate the class and call init function, then the loop starts and I get the text in my console every 1 second :
var ins = new MYCLASS();
ins.init();
Why when I set the instance to null, the thread does not stop? or any time I create a new instance and assign it to the previous instance name, it increases the calls.
in my production code, I do not have infinite loop, but I do have some business logic. do I need to be worried about performance when I create a new instance?
I have a Javascript class like below:
var MYCLASS = function(elem, data, op) {
var options = {};
var loopForEver = function() {
console.log('I cant stop me');
setTimeout(function() {
loopForEver();
}, 1000);
}
this.init = function() {
loopForEver();
}
}
when I instantiate the class and call init function, then the loop starts and I get the text in my console every 1 second :
var ins = new MYCLASS();
ins.init();
Why when I set the instance to null, the thread does not stop? or any time I create a new instance and assign it to the previous instance name, it increases the calls.
in my production code, I do not have infinite loop, but I do have some business logic. do I need to be worried about performance when I create a new instance?
Share Improve this question edited Jul 23, 2015 at 12:23 Tushar 87.3k21 gold badges163 silver badges181 bronze badges asked Jul 23, 2015 at 12:22 Ahmad MousaviAhmad Mousavi 6011 gold badge8 silver badges19 bronze badges2 Answers
Reset to default 4When you call setTimeout it is not bound by the function that called it. You need to add a property to object called something like timeOutID
. As long as the function is still required being used by something like setTimeout it will remain in scope.
var MYCLASS = function(elem, data, op) {
var options = {};
var timeOutID = null;
var loopForEver = function() {
console.log('I cant stop me');
timeOutID = setTimeout(function() {
loopForEver();
}, 1000);
}
this.init = function() {
loopForEver();
}
this.stop = function () {
clearTimeout(timeOutID);
}
}
You have a memory leak.
In other words, memory leaks may occur when objects, which are now unreachable, are still kept in memory because they are being referenced somewhere else in the call stack.
Nullifying the instance doesn't clear from memory other references to that object. See this answer to "Can an object automatically delete itself in javascript once it has achieved its purpose?"
In fact, your setTimeout
call is repeatedly creating a new execution context each with its own untouchable Activation object, which are unaffected by assigning the original instance to null
.
An excerpt from "Understanding delete" (Perfection Kills by kangax) explains it this way:
When a function is executed, it is said that control enters execution context…; that code might call a function, with its own execution context; that function could call another function, and so on and so forth.
Even if function is calling itself recursively, a new execution context is being entered with every invocation.
…when in Function code, a Variable object is … a so-called Activation object. Activation object is created every time execution context for Function code is entered.
Note that Activation object is an internal mechanism and is never really accessible by program code.
If you want to nullify the instance, you should clean it up first by clearing the timed recursive call using .clearTimeout()
.