Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

memory leak with setInterval

Status
Not open for further replies.

DaveC426913

Programmer
Jul 28, 2003
274
CA
This is a real showtopper.

My application needs to run for hours at a time without resetting, using limited processing cycles and limited memory. It uses Ajax to poll the server every few seconds.

Unfortunately, the setInterval to used to make the poll tick over is leaking.

I'm running a barebones test to see how bad it is.

var x;
function startme(){
x = setInterval("loop()",100);
}
function stopme(){
clearInterval(x);
}

var imAlive = 0;
function loop(){
document.getElementById('target').innerHTML = imAlive;
imAlive++;
}

This ran OK overnight. 200,000 ticks and still going.

But anything more complex and the setIntervals can start overlapping. Then the memory slowly starts creeping up. With a very simple interface, the poller ran for less than an hour before burning through all the memory.

Even stopping the setInterval to let it catch up doesn't work. If I watch the system resources they're always a many k higher each time.


I need to figure out a way of ensuring it doesn't eat up all the memory - or we're dead in the water!
 
and the setIntervals can start overlapping"
are you calling startme repeatedly?
if so, why?
 
No, not calling startme repeatedly. Just once upon page load via a 'Start' button.
 
Addendum (sorry, there's no 'edit' functionality):

The above runs OK, but when I add an Ajax call, the loop may take longer to complete than the interval. So the timer fires again before it's complete.

I HAVE resolved one aspect of that. Rather than setInterval, I simply wait until the Ajax call returns before callnig a setTimeout. The upshot of this is that there should (theoretically) be only one cycle occurring at a time, reagrdless of how long any cycle takes to complete.

Unfortunately, this does NOT solve the leak. The memory creeps up significantly with every cycle. I've optimaized my code to do its own housecleaning but that does not alleviate the problem.

Trying to figure out how I can write a barebones loop that includes an Ajax call that I can post publicly (i.e. does not try to hit my private server).
 
Huh. I will definitely give that a try and report back. Thanks.
 
Alas, no joy. Still climbs at about 10k per iteration.

(BTW, this is in Google Chrome.)

Here is my code:

var x;
var imAlive = 0;
var baseUrl = " var sid = null;
var did = "66:66:00:00:00:EF";
var looping = null;
var imRetrying=0;
var loopfreq = 2;

function startloop(){
login();
}

function login(){
if (!sid){
status("Requesting login...");
var xhReq = new XMLHttpRequest();
xhReq.onreadystatechange = onGetSectionsReturned;
xhReq.open("GET", baseUrl + "?fun=srnDeviceLogin&did=" + did,true);
xhReq.send( null);

}
else{
status("Already logged in...");
}

function onGetSectionsReturned() {
if (xhReq.readyState != 4) {
return;
}
else{
jsonObj = string2json(xhReq.responseText)
raw(xhReq.responseText);
if (jsonObj.RootName=="items"){
sid = jsonObj.sid;
status(sid);
aliveTicker();
imRetrying=0;
if (looping){
setTimeout("logout()",loopfreq);
}
}
else{
imRetrying++;
status("Login attempt" + imRetrying + " failed. Retrying...")
setTimeout("login()",5000);
}
xhReq.onreadystatechange = null;
xhReq.abort = null;
xhReq = null;
jsonObj = null;
}
}
}


function logout(){
if (sid){
status("Requesting logout...");
var xhReq = new XMLHttpRequest();
xhReq.onreadystatechange = onGetSectionsReturned;
xhReq.open("GET", baseUrl + "?fun=srnDeviceLogout&sid=" + sid,true);
xhReq.send( null);

}
else{
status("Not logged in...");
}

function onGetSectionsReturned() {
if (xhReq.readyState != 4) {
return;
}
else{
raw(xhReq.responseText);
jsonObj = string2json(xhReq.responseText)
if (jsonObj.RootName=="items" && jsonObj.rcd==0){
sid=null;
status("sid= n/a");
imRetrying=0;
if (looping){
setTimeout("login()",loopfreq);
}
}
else{
imRetrying++;
status("Logout attempt " + imRetrying + " failed. Retrying...")
setTimeout("logout()",5000);
}
xhReq.onreadystatechange = null;
xhReq.abort = null;
xhReq = null;
jsonObj = null;
}
}
}



function startloop(){
if (!looping){
looping = true
}
}

function stoploop(){
if (looping){
looping = false;
}
}


// generic fns

function aliveTicker(){
imAlive++;
o = document.getElementById('imAlive')
o.innerHTML = imAlive;
o = null;
}

function escapeHTML(HTMLString){
HTMLString = HTMLString.replace("<","&lt;");
HTMLString = HTMLString.replace(">","&gt;");
return HTMLString;

}

function string2json(string){
return xml2json(string2xml(string))
}
function string2xml(string){
return XMLObjectifier.textToXML(string);
}
function xml2json(xmlObj){
return XMLObjectifier.xmlToJSON(xmlObj," ");
};

function raw(inString){
o = document.getElementById('raw')
o.innerHTML = escapeHTML(inString);
o = null;
}
function status(inString){
o = document.getElementById('status')
o.innerHTML = inString;
o = null;
}
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top