Js memory leaks are usually caused by closures, and we often feel confused when determining whether there is a memory leak. Usually we use codereView to determine whether there is a leak, but this method is not objective enough. We need an objective way to prove that a leak exists.

Chrome Devtool

In fact, Devtool already provides a tool for checking, which is the Memory panel. It looks something like this.

We can use this tool to take a snapshot of the memory state of the page at a certain time. This snapshot contains all the Dom nodes and JS objects on the page at that moment. We can verify the existence of a memory leak by searching for potentially leaked JS objects.

For example,

This example clearly has a memory leak. L1 is accessed by event handlers and cannot be freed. So let’s actually do that.

function leak(arg) {
    this.arg = arg;
}

function test() {
    var l1= new leak('It is a leak');

    document.body.addEventListener('click'.function() {
        l1.arg = 'Here you are! '
    })
}

test();
Copy the code

Step 1 Record a snapshot

Select the Heap Snapshot and click on the little dot in the upper left corner. You can see the generated snapshot after a few seconds.

Step 2 Search for potential leaks

Enter the type of object that might leak at the top, and then look for instances in memory where the type changed.

As shown in the figure above, we find an instance object. With some data matching, we were able to prove the existence of the leak.

Step 3 Correct this leak

We can eliminate the leak by deleting the event binding after the event starts

function leak(arg) {
    this.arg = arg;
}

function test() {
    var l1= new leak('It is a leak');

    function l() {
        console.info('Here you are! ')
        l1.arg = 'Here you are! '
        document.body.removeEventListener('click', l);
    }

    document.body.addEventListener('click', l)
}

test();
Copy the code

At this point, Leak no longer has instance objects.