Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will not resolving a deferred create memory leaks?

Suppose the following code:

var deferred = $.Deferred();
deferred.done(function(){
    // do something with events, references to dom, etc...
});

deferred.fail(function(){
    // do something with events, references to dom, etc...
});
  1. If I never end up calling resolve() or fail(), will this cause memory leaks, since I keep references in the callbacks?

  2. If I call one, but not the other, will the other be garbage collected? So if I call fail(), will jquery get rid of done()?

I might be thinking wrong entirely, but would like some clarification. The closest I have found thus far was this Shall I always invoke either JQuery Deferred.resolve or Deferred.reject?. But the use case is a bit different, since in that example the user has never defined a callback for fail().

I also came across this, Can jQuery deferreds be cancelled?, however I am not trying to cancel a deferred.

I understand that this is not best practice, but for the purpose of the question I am still curious if it would cause memory problems.

Thank you,

like image 996
Levon Tamrazov Avatar asked Apr 20 '15 19:04

Levon Tamrazov


People also ask

What is the main cause of memory leaks?

DEFINITION A memory leak is the gradual deterioration of system performance that occurs over time as the result of the fragmentation of a computer's RAM due to poorly designed or programmed applications that fail to free up memory segments when they are no longer needed.

How did you avoid memory leaks?

The best way to avoid memory leaks in C++ is to have as few new/delete calls at the program level as possible – ideally NONE. Anything that requires dynamic memory should be buried inside an RAII object that releases the memory when it goes out of scope.


1 Answers

If I never end up calling resolve() or fail(), will this cause memory leaks, since I keep references in the callbacks?

If the deferred variable itself is no longer reachable by any of your code (which also means there are no other promises depending upon this one), then it will be eligible for garbage collection even though it was never resolved or rejected. If you want more specifics on what "reachable" means, then it would be best for you to show your actual code that you're concerned about.

If, on the other hand, you're still holding onto the deferred variable somewhere or other promises that are still reachable are depending upon this promise (which means those promises have a reference to this one), then it doesn't matter whether the deferred object has been resolved or not, it will still be alive and cannot be garbage collected.

Promises are just ordinary Javascript objects when it comes to garbage collection so they follow all the same garbage collection rules as ordinary objects.

If I call one, but not the other, will the other be garbage collected? So if I call fail(), will jquery get rid of done().

Code itself doesn't get garbage collected. It's the contents of variables and objects that gets garbage collected. So, in the code you show, it's the contents of the deferred variable (the promise object that variable points to) that is the subject of garbage collection. And, as I said above it makes no difference whether you've resolved, rejected or neither. What matters is if the object is still reachable by your code or not. If any code can still reach the deferred variable or if any other code or promises has a still reachable reference to this promise.


As an example, if I have this top level code in my page:

<script>
var deferred = $.Deferred();
deferred.done(function(){
    // do something with events, references to dom, etc...
});
deferred.resolve();
</script>

The deferred variable is still reachable and still alive so the Deferred object that it points to cannot be garbage collected.


Alternatively, if I have this:

<script>
$("#submit").click(function() {
    var p = $.get(myURL);
    p.done(function(data) {
        if (data) {
            $("#msg").html(data.msg);
        }
    });
});
</script>

Then, as soon as the ajax call completes and the .done() handler is called, then there is no longer any code that can reach that instance of the p variable because the ajax operation is done so it will release its reference to the promise and thus it can't trigger any more promise callbacks itself. And, it has gone out of scope of the click handler callback function and there are no live event handlers that could still access p so it has become unreachable. At that point, it would be eligible for garbage collection.

like image 113
jfriend00 Avatar answered Sep 18 '22 23:09

jfriend00