This is the 14th day of my participation in the August More Text Challenge. For details, see:August is more challenging

This is the third article in the memory Control chapter, Using memory efficiently

  • Part 1: V8’s memory limits and why
  • Chapter two: V8’s garbage collection mechanism

In the previous two articles, nodeJS was limited in its use of memory due to the limitations of the V8 garbage collection mechanism (about 1.4 GB on a 64-bit system and 0.7 GB on a 32-bit system). In addition, we analyzed a V8 garbage collection algorithm for old and new generations.

This article is about V8. What do we need to pay attention to when developing to make V8 garbage collection work more efficiently

scope

The first is scopes. In JavaScript, scopes are function calls, with, and global scopes.

Such as:

let foo = function() {
    let local = {};
}
Copy the code

Each time foo is called, the scope is created. After the function is executed, the scope is destroyed, and the local variable is destroyed along with the scope. Objects referenced by local variables have a short lifetime and are divided into the new generation of From space. After the scope is freed, the referenced object is freed in the next garbage collection

Identifier lookup

let bar = function () { 
    console.log(local);
};
Copy the code

For example, in this example, when executing the bar function, the local variable will be looked up in the current scope first. If not, the local variable will be looked up in the previous scope until the global scope is found. If not, an undefined error will be thrown.

Active release of variables that are global (not declared via var, let, const, or defined under global) is not released until the process exits, causing the application’s object to live in memory (in the old generation).

If memory needs to be freed, you need to either delete the reference using DELETE (not recommended because it might interfere with V8 optimizations) or dereferencing by assignment.

global.foo = "I am global object";
global.foo = undefined;  // or null;
Copy the code

closure

As we said earlier, access to objects in the scope chain is upward, and external objects cannot be accessed internally. For example, the following example will cause an error:

let foo = function () {(function () {
        var local = "Local variable"; } ());console.log(local); 
};
Copy the code

A method that allows an outer scope to access variables in an inner scope is called a closure. This is due to the nature of higher-order functions: functions can be used as arguments or return values

let foo = function () {
    let bar = function () {
        let local = '123';
        return function () {
            returnlocal; }}let baz = bar();
    console.log(baz())
}
foo();
Copy the code

Normally local is reclaimed with the scope destruction of bar, but since bar returns a function that has access to local, external functions can access local through this function.

The problem with closures is that once a variable references an intermediate function, the intermediate function is not freed, and the outer scope of the intermediate function is not freed until there are no more references

conclusion

Closures and global variables cause memory not to be recollected immediately, and due to V8’s memory limitations, care should be taken not to allow such variables to grow indefinitely, as they increase the number of objects in the old generation.