preface

Happy August, everyone. I am STUDENT D from the push front team. Today I would like to briefly share with you JavaScript garbage collection mechanism and memory management strategy.

As we learn about closures, one of the more important disadvantages is that improper closures (pre-IE9) can cause memory leaks.

A memory leak is a waste of memory resources caused by a program’s dynamically allocated heap memory not being freed for some reason.

Why did this happen before IE9? The reason is that prior to IE9, the garbage collection mechanism used reference counting.

JavaScript has two mechanisms for garbage collection (GC)

1. Reference counting

The core of the algorithm is to track the number of references to each object. Whenever there is a variable whose value is a reference to an object, the reference to that object is +1. Conversely, if every time there is a variable that references the object changes so that the object is no longer referenced, the reference to the object is -1.

When the reference value of an object is 0, the object is not referred to by any variable, that is, no variable can access it. Therefore, the memory space in which the object resides can be released for reclamation.

Prior to IE9, this approach resulted in a memory leak scenario similar to the following

function bar(){
    let a = {}
    let b = {}
    a.foo = b
    b.foo = a
}
bar()
Copy the code

In this scenario, because the properties of A and B are referenced to each other, the memory space where AB is located will not be reclaimed when the function is completed because the reference count of a and B is not zero.

2. Mark removal method

The method can be divided into two stages

  • The mark phase

    The markup phase is a process of finding accessible objects; Garbage collection starts with a set of objects Pointers called the root set. This includes the execution stack and global objects. The garbage collector then tracks every pointer to a JavaScript object and marks the object as accessible, as well as the pointer to every property in the object and marks the object as accessible, recursively, until there are no traversable paths for all the nodes.

  • Sweep phase

    At the end of the flag phase, if an object is not marked, indicating that it cannot be accessed from the root node, the garbage collector reclaims that memory.

As shown in the figure, when the depth-first traversal starts from the root node, the object that cannot be traversed means that the root node cannot be accessed.

Objects marked in red in the figure are unmarked and will be collected by the garbage collector when the traversal is complete.

It can be seen that flag clearance can solve the problem of memory leaks caused by objects referencing each other.

Currently, the JavaScript implementations of Internet Explorer, Firefox, Opera, Chrome, and Safari all use a tag-clear garbage collection policy (or something similar), but at different intervals.

Memory reclamation policy of the V8 engine

Generational memory

In the memory structure of the V8 engine, heap memory is divided into two categories for processing. New generation memory and old generation memory.

  • New generation memory

New generation memory is the memory that is temporarily allocated and has a short lifetime.

The new generation of memory can be divided into two regions: from-space and to-space.

The from region can also be subdivided into nursery children and intermediate children

  • Old memory

Old generation memory is resident memory and has a long life.

The overall memory allocation is shown here

Scavenge algorithm

A new generation of memory garbage collection algorithm is called Scavenge

process

The “From” part indicates the memory in use, and the “To” part indicates the current free memory.

  • When garbage collection is performed, the V8 engine checks the objects in the From memory, copies the living objects To the To memory, and reclaims the non-living objects directly.

  • When the replication is complete, the From memory is cleared, and the From and To roles are switched. The process is called a Scavenge algorithm.

features

One might say, why not just allocate all the memory to From and reclaim the nonliving objects?

The answer is no, because the heap memory is allocated continuously, so after garbage collection, there may be discontinuous memory fragmentation, so the scattered memory space will lead to larger objects, not space allocation.

Exploiture. The garbage collection process of Scavenge algorithm is To copy the living object between the From space and the To space, and complete the role exchange between the two Spaces at the same time. Therefore, the algorithm has an obvious disadvantage, wasting half of the memory for copying.

Advantages: Scavenge algorithm is a kind of typical sacrifice space for the algorithm of time, for the old generation of memory, may store a large number of objects, if using this algorithm, in the old generation is bound to cause memory resources waste, but in the new generation of memory, most of the short life cycle of an object, in time efficiency, So it’s a good fit for this algorithm.

promotion

If a variable in the new generation survives multiple garbage collections. The object is considered to be an object with a long declaration cycle and is placed in the memory of the old generation. The process of transferring the object from the new generation to the old generation is called promotion.

There are two conditions for an object to be promoted:

  • Be insane. You have experienced the Scavenge algorithm.
  • To (currently idle) Space Memory usage exceeds 25%

Old generation garbage collection

The old generation of garbage collection uses mark-sweep, but mark-sweep causes the aforementioned memory fragmentation problem.

To solve this problem, there is also a mark-compact mechanism in the flag clearance process, which moves all the living object memory space forward after a flag clearance.

Since you’re moving objects, it can’t be very fast, and in fact is the most time-consuming part of the garbage collection process

Incremental tag

Because of the single-threaded mechanism of JavaScript, when the V8 engine does garbage collection, it blocks the execution of the application layer business logic. This action is called a “total pause.”

Prolonged “full pause” garbage collection makes the user experience very bad and can seriously affect performance.

So in order to avoid this problem. Since 2011, V8 has replaced the “full pause” flag with an incremental flag. The improved marking method reduces the maximum pause time to 1/6 of the original.

Incremental markup, the process of a complete pause, is broken up into “small steps”, each of which allows the logic in the JavaScript application layer to execute for a short time. Garbage collection and application logic alternate until markup is complete.

Author: D Link: juejin.cn/post/6992.. …