#JavaScript #V8 #GarbageCollection

V8, a JavaScript engine implemented in Chrome, is known to perform periodic garbage collection. While searching for information related to this, I will try to follow Daniel Khan’s writing and summarize my feelings. The article can be read at the link below.

Understanding Garbage Collection and Hunting Memory Leaks in Node.js

Resident Set

V8 operates memory with a structure called ‘Resident Set’. Just as the Java Virtual Machine (JVM) divides memory into several segments, it is said that memory is divided into Code, Stack, and Heap areas by the Resident Set structure. We need to know more about this part.

process.memoryUsage()

Node.js, like Chrome, uses V8 to interpret JavaScript. Node.js seems to provide a function called process.memoryUsage(). It seems that you can know the size of the Resident Set, the size of the heap, and the size of the heap being used.

Garbage Collection

Unlike conventional C and C++ where programmers have to allocate and deallocate memory directly, JavaScript does not need to do so. This is because, among elements used in JavaScript, unused elements are automatically removed from memory by garbage collection. In particular, V8 provides two types of garbage collection for performance reasons.

  • Scavenge: fast, frequent but incomplete garbage collection - Mark-Sweep: slow, infrequent, but complete garbage collection

Memory Leak

A ‘Memory Leak’ occurs when a specific element continues to occupy memory even though it will not be used in the future. The moment memory leak occurs and it exceeds the allocatable memory, the process will die.

JavaScript’s Scope

The author provides code that intentionally induces a memory leak. The code is not included in this article. The more the code calls replaceThing(), the more memory leaks occur. Looking at the function, originalThing refers to the same object as theThing, and this object was created when the replaceThing() function was called before. When the current replaceThing() function is called, theThing refers to the newly created object.

The global object theThing is updated every time the replaceThing() function is called and refers to the newly created object each time. So the originalThing, i.e. the object created by the previous replaceThing() function call, is no longer used and must be removed from memory originally, by garbage collection.

Nevertheless, the cause of the memory leak is in the unused() function. To understand this, you need to understand the scope of JavaScript. In JavaScript, when a function is nested inside a function, that is, when a function is nested, the inner function can refer to elements located in the outer function. After all, someMethod(), a method of theThing in replaceThing() function, can refer to unused(), a function object located in an external function.

’theThing’ and ‘originalThing’ seem unrelated at first glance. However, the method someMethod() owned by the object theThing refers to the function object unused, which in turn refers to the object originalThing. In the end, originalThing is not removed from memory and a memory leak occurs.

Closure

Because of the wide scope of JavaScript, you can easily implement closures, which were cumbersome to implement in C or C++. Closures are often used as callbacks. This is because the wide effective range allows it to operate in the context of the ‘declaration’ even at the ‘call’ moment of the function. This part needs to be explored a bit more.

Inspector

A developer tool that web developers will be familiar with, ie, the web inspector, contains many unexpected functions. In this text, the memory leak is shown with the ‘Inspector> Profile> Heap Snapshot’ function. Inspector seems to be a very helpful tool not only for web developers, but also for browser developers. Contrary to the main text, I checked that a memory leak occurred with the JavaScript console provided by the inspector.

console memory leak