user3599803
user3599803

Reputation: 7044

javascript - is that a memory leak?

My case is not exactly this, but the concept is very similar, I have a content which get loaded via ajax, with a script inside.

page1.html:

<div id="ajax-content"></div>
<button onclick="loadContent()">do ajax</button>
<script>
function loadContent() {
  $.get('page2.html', function(response) {
      $("#ajax-content").html(response);
  });
}  
</script>

page2.html:

<button id="btn">button</button>
<script>
(function() {
  var MyModule = {
      main: function() {
        $("#btn").click(function(){ 
            alert("btn click"); 
            // some code
        });
      }
      // some more functions...
  };    
  MyModule.main();
})();
</script>

Assume that the "do ajax" button will be clicked more than once.
[Each click will load content from the server, which I want to be refreshed frequently. ]
The loaded page (page2.html) has some interactive widgets in it, hence the script tag is get loaded and executed there.
As you can see, I put all the code in page2 in a self invoking function (module pattern), since I don't want to pollute the global scope.
Since each ajax request led to call the script again, MyModule is created multiple times, and I'm not sure if the previous copy will get GC'ed.
So here I my thought of how this is happening, tell me if I'm wrong -

  1. button "do ajax" is pressed (page1.html), the function loads the contents of page2.html, and put the result inside the div.
  2. The self invoking function get executed, creates MyModule. The main function in my module get called
  3. The main function bind an event handler to the button with id='btn'. so now we have these references: btn -> handler -> all of the self invoking function scope.

Now here is where I'm not sure: if I remove the button with id='btn' from the document, it's handler can be GC'ed => the entire self-invoking function scope will be GC'ed ?
If I'm correct, since each ajax call will replace the html of the div[id='ajax-content'], no memory leak will happen.

Upvotes: 2

Views: 96

Answers (1)

c-smile
c-smile

Reputation: 27470

TL;DR: In ideal browser implementation you should not have memory leak there.

Anonymous function declaration and invocation

(function() { ... })();

, if taken alone, creates Function object and executes it. As soon as it will not put any references to its inner scope objects it will be cleared entirely from heap on next GC iteration.

But in your case you have $("#btn").click(function(){...}) - single reference that will hold inner scope objects of your script. So until #btn DOM element existence those objects will be hooked by the DOM.

If you will remove #btn and remove the <script> DOM element itself then the GC will be able to clean you dynamic script entirely.

Just don't put references of such temporary objects into global collections (WeakMap is OK for that). Without proper maintenance of such collections (e.g. removing unused) you may observe memory leak alike symptoms.

Upvotes: 1

Related Questions