An "engine" is a self-contained, but externally-controllable, piece of code that encapsulates powerful logic designed to perform a specific type of work.
Every major browser comes with one already built-in…
- Edge used to use Chakra (now it uses the Blink and V8)
and so on…
In this series I am going to talk about the V8 and today I will talk about Garbage Collection.
But, first a quick introduction.
What is this V8 thing?Citing the official docs:
It is written in C++ and it is embedded in Open Source projects like NodeJs and Deno.
It is what provides all the data types, operators, objects and functions.
It is what optimizes the code to run faster.
It is what makes the thing you write, happen.
💡 - Did you know you can access V8 native syntax in NodeJs by passing the —allow-natives-syntax-flag?
Open SourceThe V8 source code can be downloaded, studied and improved by everyone. The docs has also a section for everyone who would like to contribute to the development.
Build from Source
Implements ECMAScriptWhat does it even mean?
What is ECMAScript?
ECMA (European Computer Manufacturer’s Association) is an association that develops standards for technologies. ECMA-262 is a standard that contains the specification for a general purpose scripting language. This specification is called ECMAScript.
A standard is a document that provides rules, guidelines or characteristics for activities or their results, for common and repeated use. Standards are created by bringing together all interested parties including manufacturers, users, consumers and regulators of a particular material, product, process or service.
Allocation —> Usage —> Release
Some languages require a manual allocation and release of memory
int* ptr; ptr = new int; // Dynamically allocating memory for an int variable *ptr = 12; cout << *ptr << endl; delete ptr; // Deallocate memory
Heap and Stack
We can simply define the stack as the place where static data, including method and function frames primitives data types and pointers to objects get stored, while the memory heap is the place where the non primitves data types are stored. The Heap is where Garbage Collection takes place.
All variables first point to the stack. If it is not a primitive value, the stack contains a reference that points to the Object in the heap.
💡 - Why can I push elements in const Arrays ?
When we write our code and create primitives, objects, functions we just learned that it takes memory. So when is the cleaning performed?
The way V8 achieves that is through the implementation of some advanced concepts.
If an object is currently reachable within the runtime must be kept, and any unreachable objects may be collected.
Sweeping is a process where gaps in memory left by dead objects are added to a data structure called a free-list.
A free list is a data structure generally used for dynamic memory allocation that connects unallocated regions of memory together in a linked list.
When new data has to be allocated, V8 looks at the free list to find an appropriate chunk of memory.
Compaction is the process of copying surviving objects into other pages that are not currently being compacted (using the free-list for that page)
Although you do not need to worry about freeing memory everytime, this doesn’t exempt you from carefully reviewing your code.
Things such as badly implemented recursion or infinite loop can extinguish your available memory pretty quick and/or worse lead to memory leaks.
V8 splits the heap into different regions called Generations.
- Young Generation - split further in Nursery and Intermediate
- Old Generation
Starting from the nursery, if an object survive a Garbage Collection it is moved into Intermediate generation at first and then, after another survival to Old Generation.
But why is that?
Most objects die youngV8's generational heap is designed to exploit that assumption about objects' lifetime, the Generational Hypothesis.
Rememebering the concept of Compaction and assuming that objects are more likely to die in initial generations, then by moving only the objects that survive, V8 only pays a cost for copying that is proportional to the number of the surviving objects… and not the number of their allocations.
Orinoco is the codename of the Garbage Collector project to make use of the latest and greatest parallel, incremental and concurrent techniques for garbage collection, in order to free the main thread
Geez, what does that even mean?
Well, one metric in measuring the Garbage Collection is the time that the main thread spends paused while GC is performed.
In traditional Stop The World garbage collectors this time can add up and become a burden on user experience (latency or poor rendering), this is why Orinoco introdcued 3 techniques to make the collection more powerful.
V8’s stop-the-world, generational, accurate garbage collector is one of the keys to V8’s performance.
I won't go deeper on how the Garbage Collection is implemented in V8 because such is a huge and complex topic and one article wouldn't be really enough. I introduced the main concepts behind V8 and how it allows us to write code without thinking too much about memory management (always keeping the best practices in mind though). V8 is an insanely huge piece of technology that implements a lot of clever concepts and I cannot wait to unveil them one by one.
See ya in next article.