为什么这个JavaScript会占用我所有的记忆?

时间:2012-05-31 10:34:35

标签: javascript memory-leaks

所以我有一个小的javascript应用程序,每分钟(或其他)从服务器接收一对数字,并在一分钟内每秒更新一个div(或其他),以便div中显示的值逐渐从第一个值增加到第二个值。它只是简短,我会在问题的底部发布代码。

该函数包含两个子函数 - 其中一个函数执行ajax调用以更新这两个值,其中一个函数使用两个值之间的值更新div内容。当ajax函数具有来自服务器的响应时,使用setInterval来调度div更新函数,并且当div更新函数检测到是时候更新这两个值时,它会清除设置的间隔并调用ajax函数。因此,这两个功能永远相互呼唤。

我声明了外部函数中两个子函数使用的每个变量,因此子函数都不会创建任何新变量,并且每次都允许两个子函数完全完成(感谢ajax函数中的setInterval)

内存使用率几乎每秒都在上升,每次调用doDivRefresh时都必须这样,但我不清楚每次调用它时新内存的作用是什么 - 它不会创建任何变量。

帮助!

/**
 * 
 * Periodically gets the latest values for a stat and changes the contents of a
 * div so that is ticks up from the previous value to the latest value
 * 
 * @param divID
 *            The id of the div to update
 * @param URL
 *            The URL that provides the values
 * @param updateDivFrequency
 *            How often the value displayed in the div is updated, in
 *            miliseconds
 * @param updateDataFrequency
 *            How often the underlying data is updated from the server, in
 *            seconds
 * 
 */
function updateStatOverPeriod(divID, URL, updateDivFrequency, updateDataFrequency)
{
    var somethingDoer = new function()
    {
    };
    var request = new XMLHttpRequest();
    var currentValue = "";
    var previousValue = "";
    var latestValue = "";
    var it = 0;
    var currentTime = new Date();
    var endTime = new Date().getTime();

    function doDivRefresh(endTime)
    {
        if (currentValue != null)
        {
            currentValue = currentValue + it;
            document.getElementById(divID).innerHTML = addCommas(parseInt(currentValue));
        }
        else
        {
            document.getElementById(divID).innerHTML = "<DIV CLASS=\"error_message\">No data</DIV>";
        }
        // If it's time to refresh the data end this loop and call the starting
        // off method again
        currentTime = new Date();
        if (currentTime.getTime() >= endTime)
        {
            clearInterval(somethingDoer);
            doAJAX();
        }
    }

    function doAJAX()
    {
        // If browser supports javascript
        if (window.XMLHttpRequest)
        {
            // Connect to the server and get the new pair of values
            request = new XMLHttpRequest();
            request.open('get', URL);
            request.onreadystatechange = function()
            {
                // Once...
                if (request.readyState == 4)
                {
                    // we've got...
                    if (request.status == 200)
                    {
                        // the response
                        if (request.responseText)
                        {
                            // Parse the response and work out our iterator
                            previousValue = parseFloat(request.responseText.split("&")[0]);
                            latestValue = parseFloat(request.responseText.split("&")[1]);
                            if ((previousValue == 0) || (latestValue == 0))
                            {
                                it = parseFloat('0.00');
                            }
                            else
                            {
                                it = parseFloat((latestValue - previousValue) / (updateDataFrequency / updateDivFrequency));
                            }
                            // Set up the doRefreshDiv function in a loop that
                            // will exit and re-call this function
                            // once updateDataFrequency has elapsed
                            currentValue = previousValue;
                            endTime = new Date().getTime() + updateDataFrequency;
                            doDivRefresh(endTime);
                            somethingDoer = setInterval(function()
                            {
                                doDivRefresh(endTime);
                            }, updateDivFrequency);
                            alert("end of ajax response function()");
                        }
                        else
                        {
                            document.getElementById(divName).innerHTML = "<DIV CLASS=\"error_message\">Error - no data received from server</DIV>";
                        }
                    }
                    else
                    {
                        document.getElementById(divName).innerHTML = "<DIV CLASS=\"error_message\">Error - server returned " + request.status + "</DIV>";
                    }
                }
            };
            request.send(null);
        }
        else
        {
            console.error("No window.XMLHttpRequest, does this browser support AJAX?");
        }
        alert("end of doAJAX()");
    }

    // Start
    updateDataFrequency = updateDataFrequency * 1000;
    doAJAX();
}

3 个答案:

答案 0 :(得分:1)

这是根据jslint.com纠正的前四行:

function updateStatOverPeriod(divID, URL, updateDivFrequency, updateDataFrequency) {
    "use strict";
    var somethingDoer = function() {};
    var request = new XMLHttpRequest();

将代码粘贴到那里并检查常见的JS错误。看来这段代码要么是从其他语言转换为JavaScript,要么是不熟悉JavaScript的人......

请参阅我的回答javascript memory leak以了解内存泄漏。我仍然认为Drip是查找和理解内存泄漏的非常好的工具。

答案 1 :(得分:0)

我同意new Date()总是代价高昂。现在,您只需要执行此代码以定期刷新值,您可以使用setTimeout("doAJAX()",2000);,并且可以指定间隔(以毫秒为单位),而不是使用日期函数进行检查。这应该是有帮助的,在另一种情况下你可以使用jquery.Ajax如果你感兴趣,因为你可以专注于你感兴趣的领域而不是自己处理XMLHttpRequest

答案 2 :(得分:0)

[head slap]

感谢答案的人,但真正的问题是调用脚本的元素中的拼写错误。由于a / where我打算放*一个脚本被调用大约一毫秒而不是每分钟一次!