preface

In JS we all know that raw data types are stored in stack space and reference data is stored in heap space. In this way, we solve the memory allocation problem of data.

However, some data may no longer be needed after it is used, which is often referred to as junk data. If the garbage data is kept in memory, the memory will be used more and more, so the garbage data needs to be reclaimed to free up limited memory space.

Garbage Collection strategy

In general, garbage data collection can be divided into manual collection and automatic collection.

  • Manual reclamation: For example, C/C++ uses a manual reclamation strategy, where the code controls when memory is allocated and when memory is destroyed.
  • Automatic collection: Like JavaScript, garbage data generated is released by the garbage collector and does not need to be released manually through code.

Memory reclamation in js

In JS, the garbage collector periodically finds data that is no longer used and frees up the memory space it occupies.

In the case of global and local variables, local variables in a function are no longer needed at the end of the function execution, so the garbage collector recognizes and releases them. With global variables, the garbage collector has a hard time determining when they are not needed, so use them sparingly.

There are two modes of garbage collection

So how does the garbage collector detect whether a variable is needed? There are basically two kinds of checks, reference counting and tag clearing.

Reference counting

The language engine has a “reference table” that holds the number of references to all resources (usually values) in memory. If the number of references to a value is zero, that value is no longer used, and the garbage collector collects it.

In the figure above, the two values in the lower left corner have no references, so they can be freed.

Const arr = [1, 2, 3, 4]; console.log("hello world");Copy the code

In the above code, the array [1,2,3,4] is a value that consumes memory. The variable arr is the only reference to this value, so the number of references is 1. Although the following code does not use ARR, it continues to consume memory.

If you add a line of code to remove the arr reference to [1,2,3,4], the memory can be freed by the garbage collection mechanism.

Const arr = [1, 2, 3, 4]; console.log("hello world"); arr = null;Copy the code

In the above code, arr is reset to null, and the reference to [1,2,3,4] is removed. The number of references becomes 0, and the memory can be freed.

Mark clear

The most common garbage collection method in JS is tag cleanup. Start from the root to see if an object can be reached, if it can be reached, identify the object is still needed, if not, release it, this process is roughly divided into three steps:

  1. The garbage collector creates a list of roots. Roots are usually global variables that retain references in code. In JS, we generally consider the global object Window as root, the so-called root.

  2. All roots are checked from the root, all children are recursively checked, and those that can reach from root are marked as active.

  3. Data not marked as active is determined to be no longer needed, and the garbage collector starts releasing it.

When an object has zero references, we cannot reach it from the root; On the other hand, things that cannot be reached from the root are not necessarily strictly zero references, such as circular references, so mark clearing is better than reference counting.

Note: So far, JS implementations of IE, Firefox, Opera, Chrome, and Safari have all used a marked sweep garbage collection strategy or similar strategies, with different garbage collection intervals.

conclusion

So it’s not as if garbage collection is an easy thing for programmers. Again, you need to keep an eye on memory usage: values that take up a lot of space must be checked to see if references to them still exist once they are no longer needed. If so, you must manually dereference it.