• 1 introduction
  • 2 Memory life cycle
    • 2.1 distribution
    • 2.2 the use of
    • 2.3 release
  • 3 V8 memory structure
    • 3.1 stack memory
    • 3.2 heap memory
    • 3.3 Using the Memory
  • Reclaim stack memory
  • Reclaim heap memory
    • 5.1 Two Ideas
    • 5.2 Two steps of V8 GC
  • 6 summarizes
  • data

1 introduction

In some low-level languages, such as C, we can use malloc() and free() to manually control memory allocation and release. However, in JavaScript, Garbage Collection automatically allocates and frees memory for us. Still, it’s important to understand memory management in JavaScript.

2 Memory life cycle

No matter what language you use,Memory life cycle(Memory Life Cycle), which can be divided into the following three stages:

2.1 distribution

Memory allocation is divided into:

  1. Static memory allocation
  2. Dynamic memory allocation

The difference between:

2.2 the use of

Operations such as reading and writing basic variables or attributes of objects and passing parameters all involve the use of memory.

2.3 release

The memory that is no longer used should be released in a timely manner.

3 V8 memory structure

V8’s memory structure:

  • A running program is represented by some memory, called a Resident Set.

3.1 stack memory

The stack is used for Static Memory Allocation and has the following characteristics:

  1. Manipulating data is fast because you operate at the top of the stack

  2. The data must be static and the size of the data is known at compile time

  3. In multithreaded applications, each thread can have one stack

  4. Memory management for the heap is simple and done by the operating system

  5. The Stack size is limited and Stack Overflow may occur.

  6. The value size is limited

3.2 heap memory

The heap is used for Dynamic Memory Allocation and, unlike the stack, the program needs to use Pointers to find data in the heap. Its features are:

  1. Slow operation speed, but large capacity

  2. This is where dynamically sized data can be stored

  3. The heap is shared between the threads of the application

  4. Heap management is difficult because of the dynamic nature of the heap

  5. There is no limit to the value size

Further partition of heap memory:

  1. New Space/Young Generation: Small and divided into two semi-spaces, managed by Minor Scavenger, where data is short-lived.

  2. Old Space/Old Generation: Large Space, managed by Major GC(Mark-Sweep & Mark-Compact). Further divided into:

  • 2.1 Old Pointer Space: contains an object that still has a pointer to another object

  • 2.2 Old Data Space: Contains only data

  1. Large object space: This is where the size of objects exceeds other space size limits.

  2. Code-space: This is where the just-in-time (JIT) compiler stores blocks of compiled Code.

  3. Cell Spaces, Property Cell Apace, Map Spaces: Each of these Spaces contains objects of the same size and has some constraint on the objects they point to, simplifying collection.

Page: A contiguous block of memory allocated from the operating system, which is made up of groups of pages.

3.3 Using the Memory

A visual example that simulates Stack and Heap allocation during code execution:

  • V8 Memory usage(Stack & Heap)

Reclaim stack memory

V8 will move throughPointer to record current execution state (ESP)To destroy the execution context that the function holds on the stack.

Reclaim heap memory

The Garbage Collector in V8 keeps track of the allocation and use of memory so that when allocated memory is no longer used, it is automatically freed. Also, this garbage collector is generational, that is, objects in the heap are grouped by age and purged at different stages.

There are two ways to reclaim heap memory:

  1. Reference-counting garbage Collection

  2. Mark-and-sweep algorithm: Since 2012, all modern browsers have used a mark-and-sweep garbage collection algorithm. Moreover, recent improvements in JavaScript garbage collection have been based on this algorithm.

In V8, two phases and three algorithms are used for GC:

  1. Minor GC: Scavenger and Cheney’s algorithm are used for the Cenozoic generation

  2. Major GC: For older generations, the Mark-sweep-Compact algorithm is used

5.1 Two Ideas

5.1.1 Reference counting method

Memory References is an important concept in reference counting. In the context of memory management, an object is said to reference another object if it can implicitly or explicitly access another object. For example, JavaScript objects can reference their archetypes (implicit references) and the values of their properties (explicit references).

The idea of reference counting is that once the number of references to an object reaches zero, it is treated as Garbage Collectible.

You can learn more about reference counting by using the following example code.

var o1 = {
  o2: {
    x: 1
  }
};
// 2 objects are created. // 'o2' is referenced by 'o1' object as one of its properties. // None can be garbage-collected  var o3 = o1; // the 'o3' variable is the second thing that  // has a reference to the object pointed by 'o1'.  o1 = 1; // now, the object that was originally in 'o1' has a  // single reference, embodied by the 'o3' variable  var o4 = o3.o2; // reference to 'o2' property of the object.  // This object has now 2 references: one as  // a property.  // The other as the 'o4' variable  o3 = '374'; // The object that was originally in 'o1' has now zero  // references to it.  // It can be garbage-collected.  // However, what was its 'o2' property is still  // referenced by the 'o4' variable, so it cannot be  // freed.  o4 = null; // what was the 'o2' property of the object originally in  // 'o1' has zero references to it.  // It can be garbage collected. Copy the code

Reference counting has a drawback – circular references. In the following example, two objects are created and referenced to each other, forming a loop. However, because they each have at least one reference to each other, they are not recycled.

function f() {
  var o1 = {};
  var o2 = {};
  o1.p = o2; // o1 references o2
  o2.p = o1; // o2 references o1. This creates a cycle.
}  f(); Copy the code

5.1.2 Mark removal method

Tag cleanup simplifies the definition of “whether an object is no longer needed” to “whether an object is available”.

There are two steps to mark removal:

  1. Tag: Start at the root node to find reachable nodes and tag them.

  2. Cleanup: The garbage collector frees unmarked memory.

The token cleanup method solves the problem of circular references. In the previous example code, after the function call returns, two objects are unreachable from the global object. Therefore, they will be collected by the garbage collector.


5.2 Two steps of V8 GC

5.2.1 Minor GC

The Minor GC is garbage collection for newborn areas.

The general idea for Minor GC :(this process uses Scavenger and Cheney’s algorithm.)

  1. The new generation is divided into two halves, namely “to-space” and “from-space”, where we continuously allocate memory

  2. If from-space is full, GC is triggered

  3. Find live objects on from-space and move them To the old generation if they have survived two minor GC cycles, otherwise move them To to-space

  4. To empty the from Space

  5. Switch the roles of “to-space” and “from-space”

  6. Repeat the process

A visual example that simulates the Minor GC:

  • V8 Minor GC

5.2.2 Major GC

Scavenger algorithm needs to involve data migration, so it is suitable for small data, but it is not suitable for large data in old areas.

The Major GC is a mark-sweep-compact garbage collection algorithm for old areas.

  1. Marking: Depth -first-search is performed on the heap to mark reachable objects

  2. Sweeping: Garbage collector walks through the heap and notes the memory addresses of objects not marked as active. This space is now marked as free in the free list and can be used to store other objects.

  3. Compacting: Move all living objects together to reduce fragmentation and improve the performance of allocating memory for new objects

Stop-the-world GC: This type of GC is also referred to as total pause because JavaScript runs on the main thread. Once the garbage collection algorithm is executed, the JavaScript script that is being executed needs to be paused, and the script execution can be resumed after garbage collection, resulting in performance degradation.

Resolution strategies adopted in V8:

  1. Incremental GC: GC is done in multiple Incremental steps rather than at one time.

  2. Concurrent marking and Concurrent cleaning/compression: Complete concurrently using multiple helper threads without affecting the main thread.

  3. Lazy cleanup: Refers to the delay in disposing of garbage in a Page until memory is needed to clean it up.


6 summarizes

  1. JavaScript is automatic GC, and the memory life cycle is divided into three phases: allocate memory, use memory, and free memory.

  2. Heap and Stack in V8 memory structure are introduced, as well as their characteristics and specific composition.

  3. This paper introduces two ideas of GC: reference counting and tag cleanup, and the current browsers use tag cleanup.

  4. The two phases of GC in V8 were highlighted: Minor and Major GC.

data

  • How JavaScript works: memory management + how to handle 4 common memory leaks
  • Demystifying memory management in modern programming languages
  • Memory Management-MDN
  • Garbage Collection: How is garbage data automatically collected? – dacac