4

I get new data every x seconds using jQuery Ajax and setTimeout() and it results in a memory leak. The browser memory goes up and up on each Ajax call until the browser crashes.

$(document).ready(wp.state.init);
wp.state = {
 data: {},
 init: function () {
 $.PubSub('state:refresh').subscribe(function () {
 window.setTimeout(function () {
 wp.state.refresh();
 }, 1000);
 });
 this.refresh();
 },
 refresh: function () {
 $.ajax({
 url: 'http://url_here/',
 cache: false,
 dataType: "json",
 success: function (data) {
 wp.state.data = data;
 $.PubSub('state:refresh').publish();
 }
 });
 }
}

UPDATE (based on @dez answer)

wp.state = {
 data: {},
 init: function () {
 $.PubSub('state:refresh').subscribe(function () {
 window.setTimeout(wp.state.refresh, 1000);
 });
 this.getState();
 },
 refresh: function () {
 wp.state.getState();
 },
 onSuccess: function (data) {
 wp.state.data = data;
 $.PubSub('state:refresh').publish();
 },
 getState: function () {
 $.ajax({
 url: 'http://url_here/',
 cache: false,
 dataType: "json",
 success: this.onSuccess
 });
 }
}

Notes:

  • Publisher/Subscriber ($.PubSub) implementation taken form here. Mem leak occured also before implementing PubSub so its apparently not related.
  • setTimeout is used instead of setInterval in order to perform the new Ajax call only after the old one was succesfull.
  • Of course there are other functions that listen to 'state:refresh' and use the data in wp.state.data
asked Apr 22, 2012 at 8:17
1
  • In which browsers are you seeing this? Commented Apr 22, 2012 at 11:47

1 Answer 1

1

I can see a couple of issues here, some of them may be causing your memory leak.

For starters, the first line:

$(document).ready(wp.state.init);

This is not going to execute init in the correct scope and as a result the value of this will be undefined on the line:

this.refresh();

You should do something like this instead:

$(document).ready(function(){wp.state.init();});

or amend your this.refresh() to be explicitly wp.state.refresh().

The bits I think are likely to be causing a leak are...

Every time you make the $.ajax call in refresh you're create a new function to handle the success callback. You should define the callback as another function on your wp.state object instead and pass that in as success in the same manner as you pass wp.state.init to the ready() method currently.

Similarly every time you call window.setTimeout in the function subscribed to your PubSub you're creating a function to handle that callback too. You should do the same here and extract that out into a function on wp.state.

answered Apr 22, 2012 at 23:20
Sign up to request clarification or add additional context in comments.

3 Comments

Well, I have done everything you suggested. And there is an improvement, now memory reaches something like 95,000K and then goes down to around 35,000 (garbage collector) but then it goes up to 100,000K and then down to 40,000K so there is still something leaking. I will continue trying to find all the leaks!! Thanks for your answer!
How big is the chunk of data you're getting from the service? Am assuming you omitted the code that actually updates your UI from the snippet above unless you're somehow binding to wp.state.data. Are you able to clear out wp.state.data after you're done updating your UI?
Yes, I omitted all the related functions: they subscribe to 'state:refresh' and use the data from wp.state.data to update the UI and other stuff too. The data chunk is about 20k and I'm getting it every 1 second. I don't clear out wp.state.data because all the application reads from it, I'm just overwriting it all the time with the new data. Why the garbage collector is not automatically clearing that out? You think I need to save a copy, read from it, and clear the original? How that would help? How can this cause such big memory leaks?

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.