简体   繁体   中英

Memory leak in JS

I have a javascript file with the content below.

"use strict";
$(function () {
var divs = $(".sc-frames");
var next = 0;
var currentIndex = 0;

var request = function (action, controller, div) {
    var url = "../" + controller + "/" + action;

    $.ajax({
        type: "GET",
        url: url,
        dataType: "html",
        async: false,
        timeout:10000,
        success: function (result) {

            writeResponse(result, div);
        },
        error: function () {
            $("#errorMessage").show();
        }
    });
};

var writeResponse = function (result, div) {
    $(div).hide().html(result).slideDown("slow"); 
    currentIndex = divs.index($(div));
    if (parseInt(divs.length - 1) == parseInt(currentIndex)) {
        next = 0;
    } else {
        next++;
    }
};

var createRequest = function () {
    $("#errorMessage").hide();
    $(divs[currentIndex]).empty(); 
    var div = divs[next]; 
    var action = $(div).attr("data-action");
    var controller = $(div).attr("data-controller");
    request(action, controller, div);
};

setInterval(createRequest, 30000);
createRequest(); 

});

This just makes an ajax call to 3 controller action method and post the view to the divs in order and continously one after the other.

But when I checked the performance moniter in Google chrome dev tools, it showed a js memory leak. The Js heap size is slowly increasing.

Is there a way to find out where exactly the memory leak is?

Thanks in advance.

Update 在此处输入图片说明

The Js heap size is slowly increasing.

That's not (necessarily) a memory leak. It happens as most engines use stop-the-world garbage collection, which means, that variables will stay in memory although they might could get collected already, then at some point the GC kicks in, stops the currently executing JS, checks all the references and frees memory that is not referenced anymore, and then continues execution (it is done like this as JS is very dynamic, you can't tel wether a variable that leaves the scope is completely dereferenced, if you check all variables at once you know for sure).

However, that makes garbage collection a performance costly operation. Therefore the GC tries to kick in as rarely as possible, which means that it only kicks in, if memory is needed (as it is full).

Therefore you don't necessarily have a memory leak (and I don't see one in the code). Observe the heap over a longer period of time, and wait for a few gc cycles or trigger them manually (looks like a saw then), then check wether that overall graph is increasing. If it does, you got a memory leak, as there are elements that survive garbagge collection, they are leaking.

Is there a way to find out where exactly the memory leak is?

Using most debuggers you can create a "snapshot" of the current's memory state. Take two of them, one before and after garbage collection, then compare them to find out what exactly is leaked, then it is usually possible to trace that back to the code thats leaking it.

You need to use clearInterval(createRequest);

When you no longer need the code running.

You can figure out when it doesn't happen by removing small pieces of functionality (or single lines) - then you know what causes it. However, I can't find the place where you stop the loop? Maybe this is sending the request every 30 seconds and never stops?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM