The memory lifecycle in javascript is probably like:
1. Allocate the memory needed
2. Use the allocated memory(read and write)
3. Release the allocated memory if not needed any more
When declaring a variable and initialize it, javascript engine will allocate memory for the value first and then set the variable pointing to that memory. After declaration and initialization, we may read the variable or re-assign it with other values. When the memory storing the value is not needed any more, javascript engine will automatically release it. This is also called “garbage collection”. In history, there are two main algorithm for deciding a value in memory is not needed: Reference-Counting algorithm and Mark-And-Sweep algorithm.
Reference-Counting Garbage Collection
After a memory block is allocated, javascript engine will count the number of reference to that memory block(as you assign it to a variable). When the number of reference to a memory block is 0, then that memory block will be released. This algorithm has a severe limitation that the related memory can not be released if there are cycle references. For example,
function func () {
var a = {}, b = {}
a.ref = b
b.ref = a
}
When using Reference-Counting algorithm, the memory allocated for variables a
and b
will not be released even after func()
is executed and popped out of the execution stack, since there are always at least one reference pointing at the memory block.
Mark-And-Sweep Garbage Collection
Mark-And-Sweep algorithm is mainly to check whether a memory block is reachable or not. It will start from the root(window
in client-side javascript), tracking all memory blocks which are referenced in the current context. If these memory blocks also contains references pointing to other memory blocks, they will also be marked as reachable. The process will continue until to find all referenced memory blocks. For those which are not referenced along the way(the context chain) will be marked as unreachable, and will be collected later. In such way circular reference problem could be solved, since if no reference pointing to the memory block inside function scope with circular references, they will be marked as unreachable and collected. With the obvious advantages, all modern browsers use Mark-And-Sweep algorithm to implement garbage collections.
Be Aware Of Memory Management
It’s a big mistake if you think with garbage collection we don’t have to care about memory management. As with Mark-And-Sweep garbage collection, we still have to tell the javascript engine that which memory block is not needed any more by setting variables pointing to null
. One of usual usage is closure. As we always return reference from a function to extend its lifecycle(normally a function execution stack will be destroyed after executed), we must set the related variables to null
such that javascript engine could collect that memory block. See below.
function func () {
var a = 'some value in memory'
return {
a: a
}
}
var b = func()
...
// set b to null such that the function stack could be released
b = null