Garbage Collection (js)

http://javascript.info/garbage-collection

Reachability

The main concept of memory management in JavaScript is reachability.

Simply put, reachable values are those that are accessible or usable somehow. They are guaranteed to be stored in memory.

There’s a base set of inherently reachable values, that cannot be deleted for obvious reasons.

For instance:

– Local variables and parameters of the current function.
– Variables and parameters for other functions on the current chain of nested calls.
– Global variables. (there are some other, internal ones as well)
– These values are called roots.

Any other value is considered reachable if it’s reachable from a root by a reference or by a chain of references.

For instance, if there’s an object in a local variable, and that object has a property referencing another object, that object is considered reachable. And those that it references are also reachable.

Here the arrow depicts an object reference. The global variable “user” references the object {name: “John”} (we’ll call it John for brevity). The “name” property of John stores a primitive, so it’s painted inside the object.

If the value of user is overwritten, the reference is lost:

Now John becomes unreachable. There’s no way to access it, no references to it. Garbage collector will junk the data and free the memory.

2 references

… the object is still reachable via admin global variable, so it’s in memory. If we overwrite admin too, then it can be removed.

Interlinked objects

Now a more complex example. The family:

First, let’s start from main. We have a family reference that points to the function marry. At this point know that marry‘s function data will all be pushed onto the local stack.

– return reference, not known yet
– param “man” reference, which points to the object with property name “John”
– param “woman” reference, which points to the object with property name “Ann”

garbage_collection_family_1

After the code runs through, and just before marry function pops, the snapshot looks like below. The function’s references have not been popped yet, and points to their relative objects:

garbage_collection_family_2

After the marry function pops, all its references will be removed.
Then, let’s say we decide to remove some references:

garbage_collection_family_3

Unreachable island

It is possible that the whole island of interlinked objects becomes unreachable and is removed from the memory.

The source object is the same as above. Then:

The in-memory picture becomes:

The root has unlinked, there’s no reference to it any more, so the whole island becomes unreachable and will be removed.

Internal algorithms

The basic garbage collection algorithm is called mark-and-sweep.

The following “garbage collection” steps are regularly performed:

– The garbage collector takes roots and ‘marks’ (remembers) them.
– Then it visits and “marks” all references from them.
– Then it visits marked objects and marks their references. All visited objects are remembered, so as not to visit the same object twice in the future.
– And so on until there are unvisited references (reachable from the roots).
All objects except marked ones are removed.

We can clearly see an “unreachable island” to the right side. Now let’s see how “mark-and-sweep” garbage collector deals with it.

The first step marks the roots:

The main things to know:

Garbage collection is performed automatically. We cannot force or prevent it.

Objects are retained in memory while they are reachable.

Being referenced is not the same as being reachable (from a root): a pack of interlinked objects can become unreachable as a whole.