2

If you define a function like:

function fetchData(callback) {
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
        if(xhr.readystate === 4 && xhr.status === 200) {
            callback(xhr.responseText);
        }
    };
    xhr.open('GET', 'http://example.com/', true);
    xhr.send();
}

Now imagine me running the fetchData function a lot.

So the question is, do I need/should I run xhr = null; after callback has executed?

I know that JavaScript has a garbage collector but does not setting xhr to null hurt?

This question is similar to XMLHttpRequest - freeing after use? but I feel that it didn't get an answer that explains that the object is in fact put in such a state where the Garbage Collection will remove it.

Emil Hemdal
  • 589
  • 2
  • 8
  • 27
  • 1
    this is most likely an implementation detail, as I'm pretty sure the spec doesn't say what happens – Ryan Jul 26 '16 at 15:03
  • where would you set xhr to null? setting it null inside the readystate handler would be like trying to blow up a buildilng while you're standing inside it. – Marc B Jul 26 '16 at 15:04
  • Once `callback` is run, there are no more references to `xhr`, and the entire scope gets collected. – Brian Jul 26 '16 at 15:07
  • 1
    Did you read the [answer link](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management#Garbage_collection) of the garbage collector [post](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management) you linked? – Simon Jul 26 '16 at 15:07
  • Do you mean by spec or by implementation? IIRC, MSIE will easily leak memory from XHR if you don't do special tricks. Any browser that actually follows the spec, the code question in question will cleanup automatically. – Mikko Rantalainen Nov 18 '20 at 11:17

2 Answers2

1

I highly encourage you to read entirely the mozilla documentation that you linked:

Allocate the memory you need, use the allocated memory (read, write) and release the allocated memory when it is not needed anymore. The first and second parts are explicit in all languages. The last part is explicit in low-level languages, but is mostly implicit in high-level languages like JavaScript.

Garbage collection by references:

This is the most naive garbage collection algorithm. This algorithm reduces the definition of "an object is not needed anymore" to "an object has no other object referencing to it". An object is considered garbage collectable if there is zero reference pointing at this object. There is a limitation when it comes to cycles.

Mark-and-sweep algorithm:

This algorithm reduces the definition of "an object is not needed anymore" to "an object is unreachable". This algorithm assumes the knowledge of a set of objects called roots (In JavaScript, the root is the global object). Periodically, the garbage-collector will start from these roots, find all objects that are referenced from these roots, then all objects referenced from these, etc. Starting from the roots, the garbage collector will thus find all reachable objects and collect all non-reachable objects.

Conclusion: If your object is not reachable from anywhere (in your case when you exit the function), it will be garbage collected. This is not something that you have to worry about in higher level languages.

Edit: Thanks Roland Starke for pointing out that you can read the specifications of how the garbage collector will handle the XMLHttpRequest here.

Community
  • 1
  • 1
Simon
  • 774
  • 4
  • 21
0

No you should not have to set xhr to null.

In JavaScript GC will happen once all reference to an object are removed. So as long as you don't do something crazy like:

fetchData.cache = xhr;

Then later in code reference that value:

var data = fetchData.cache;

Then you don't have to worry about doing anythign your self. The GC will get it to when its time.

Josh Allen
  • 124
  • 1
  • 4
  • @RolandStarke Sure it could. Everything is a reference so as long as the reference to that variable is used the fetchData function and in turn the xhr object could not be garbage collected. Anyway the point was to show how you could get into an issue and as long as your not doing anything out of the ordinary you will be fine. – Josh Allen Jul 26 '16 at 19:13
  • You are correct that not *everything* is reference primitive types are by value. Objects will be by reference. Updated my answer to make this more clear. [https://jsfiddle.net/22xcchge/7/](https://jsfiddle.net/22xcchge/7/) – Josh Allen Jul 28 '16 at 15:52