I have a quick question on how garbage collection works in Javascript.
If I have this code:
var c = {name : ‘Bob’};
c = {name : ‘Mary’};
In the code above the variable c is pointing to the object {name : ‘Bob’}. But then I set c to point to another object in memory {name : ‘Mary’}. What will happen to the object ({name : ‘Bob’}) that c was pointing to originally? Will that original object be deallocated in memory since there are no references to it anymore?
In another case:
var c = {name : ‘Bob’};
d = c;
c = {name : ‘Mary’};
Now, the original object that c was pointing to ({name : ‘Bob’}) would not be deallocated since d is still pointing to {name : ‘Bob’} even after "c" was changed to point to the new object: {name : ‘Mary’}. Correct?
So basically an object will not be deallocated from memory as long as there are references that are still pointing to it.
Can someone please explain to me if I am thinking about this correctly?
-
2Yes, that's correct in principle. However, when garbage collection occurs is completely up to the browser hence the expression "is made available for garbage collection" is often used rather than "is garbage collected".RobG– RobG2015年10月17日 21:52:29 +00:00Commented Oct 17, 2015 at 21:52
3 Answers 3
You have the right idea but there are some subtleties to be aware of:
Firstly, the JavaScript runtime decides when to actually run the garbage collection routine. Unused objects are marked for garbage collection, not immediately collected. GC can be quite expensive so it doesn't run continually.
Secondly, an object becomes eligible for GC when it becomes unreachable, rather than simply having no references.
If the GC only considered reference count you could create a "closed loop" of unreachable, uncollectible objects.
Consider this snippet:
var owner = { name: 'Ann' }; // Let's call this object 'Ann'
var pet = { name: 'Zizi' }; // And this one 'Zizi'
// create a loop of references
owner.pet = pet;
pet.owner = owner;
owner = null; // owner no longer refers to Ann
pet = null; // pet no longer refers to Zizi
When this code finishes running there are no top-level references to Zizi or Ann - they are unreachable . In a modern runtime (like the one in your browser), they are marked for GC and will be cleaned up when the GC routine next runs.
But what if objects were collected only when their reference count reached zero? Let's think about Zizi. It can't be collected because Ann still has a reference to it. It can't be used, since there are no available references to it.
Ann also can't be collected because Zizi refers back to it. This is a bad situation - two objects that can't be reached by user code, but also can't be garbage collected. It's a memory leak.
This kind of garbage collection algorithm, known as reference counting, caused an infamous issue in older versions of Internet Explorer: DOM nodes and event handlers could prevent each other from ever being garbage collected. Reference-counting garbage collectors are largely obsolete for that reason.
Further reading: Chrome Devtools Docs - Memory 101.
6 Comments
owner and pet no longer refer to them. You couldn't write code at the end of this program that somehow gained a reference to Ann or Zizi. Because they are unreachable, they are marked for GC (in a modern runtime).pet and owner still exist at the end. null is a value in JavaScript (just like undefined, true, 1, "hi" and so on). At the end of this snippet owner and pet both have the value null (you could try it out in your browser's JS console). They will continue to have that value until they are assigned another value, or they go out of scope (e.g. the function they are defined in completes). At that point they will cease to exist.Correct objects are garbage collection eventually when there are no references to them, assuming your code snippets are in the global scope this is true, of course if your var declaration is within a function it will be out of scope once the function has exited. An exception to this are closures, where objects on the local scope are still referenced by variables returned by the function.
I mentioned 'eventually' garbage collected above, because when objects are actually collected are subject to varying factors (memory pressure etc) and this is specific to the JavaScript engine (V8, chakra, nitro etc) being used.
Comments
MDN has a really good article regarding memory management. And it specifically discusses memory allocation and garbage collection with many examples.