Garbage Collector in V8

Let's dive in!

Let's start with the base

The principle of garbage collection is quite simple: if no one is referencing a segment of memory, for example an object, it can be considered unused and cleaned up. This principle is also called “the principle of attainability“.

The basic algorithm of garbage collection is called mark and sweep. This algorithm can also be combined with the algorithm mark-compactTogether they work as follows:

  1. The garbage collector marks all root objects.

  2. Next, all objects referenced by these roots are marked.

  3. The process is repeated for all reachable objects.

  4. After this, unmarked objects are considered unreachable and are deleted.

  5. The remaining objects are being moved (defragmented). This will reduce fragmentation and improve the performance of memory allocation for new objects.

mark-and-sweep + mark-compact

mark-and-sweep + mark-compact

There are several other garbage collection algorithms. Some of the more common ones include:

  1. Serial Garbage Collector

  2. Parallel Garbage Collector

  3. Concurrent Mark and Sweep (CMS)

  4. Garbage First (G1)

Digging deeper

How are variables, functions, and objects allocated in V8's memory? V8 uses a scheme based on the Java Virtual Machine concept (JVM) and divides the memory into segments:

V8 memory schema
  • Code Segment: the code currently executing.

  • Stack (static memory allocation): contains all primitive data types (like int, bool, string) with pointers to functions, objects, and information about method calls.

  • Heap (dynamic memory allocation): A segment of memory dedicated to storing reference data types, such as objects, arrays, and functions. This is the largest block of memory and is where garbage collection occurs.

More about each segment

Stack:

This is a memory area allocated for each process in V8. As mentioned earlier, it stores static data, including method/function frames, primitive values, and object pointers. The stack works on the principle LIFO (Last In, First Out)that is, the last element added will be the first one extracted.

Heap – the largest block of memory area, under the hood it is divided into:

Heap schema
  • Young generation – a place where new objects “live”, and most of them are short-lived. This space is small and consists of two half-spaces (from-space, to-space).

  • Old generation – a place where objects that have survived two garbage collection cycles are moved Young generation block. This space is managed by the basic garbage collection algorithm. mark and sweep. Old generation can be divided into two more subspaces:

    • Old pointer space – contains objects that have survived two garbage collection cycles and have pointers to other objects.

    • Old data space – contains only objects that have data (without references) and strings, numbers, arrays.

  • Large object space – objects whose size exceeds the size of other spaces are stored here. Large objects are never garbage collected.

  • Code space – Here Just In Time (JIT) The compiler stores compiled blocks of code. This is the only space with executable memory.

  • Cell space, property cell space, and map space – service objects that simplify garbage collection are stored here.

Conclusion

I hope this article was useful and interesting. I will be glad to any comments and questions. Thank you for your attention!

Inspired by:

  1. A tour of V8: Garbage Collection

  2. Visualizing memory management in V8 Engine (JavaScript, NodeJS, Deno, WebAssembly)

  3. The structure and operation of JVM (Java Virtual Machine)

  4. Efficient Memory Management in Node.js

My repository “Expanding Your Horizons: Node.js and JavaScript”where I write down interesting answers to questions and learn the Zen of V8.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *