javascript - 处理数组时可能发生 JavaScript 内存泄漏?

标签 javascript arrays memory-leaks google-finance

我正在使用 Humble Finance一次绘制一个点的一系列数据以实现延时效果。我的代码在下面,但我想先解释一下:

如果您不熟悉 HF,它的初始化函数采用三个 JavaScript 数组(priceData、volumeData 和 summaryData),然后将其绘制到三个图形上。这些阵列每个都包含多个 XY 对阵列。

在我的程序中,我声明了三个空的“图形”数组(priceData、volumeData 和 summaryData),然后从数据库中获取值并将它们放入名为 priceDataOrig、volumeDataOrig 和 summaryDataOrig 的“主”JavaScript 数组中。我没有将这些数组传递给 HF 并立即绘制所有数据,而是调用了一个函数 UpdateGraph(),它每 40 毫秒调用一次。 UpdateGraph() 一次将一个值(实际上是一个包含 XY 对的数组)从主数组插入其对应的图形数组,然后调用 HF 初始化函数(将图形数组传递给它),绘制三个图形。在图形数组中有 50 个点后,我开始移出最旧的点,然后再推送新点,这样一次绘制的每个图形不超过 50 个点。

此外,我正在使用 jQuery 的 load() 来加载图形,因此每当用户单击“开始”按钮时,graph.php(处理上述所有内容)都会加载到页面上的 div 中并开始绘制图形一点一点。这个想法是,用户应该能够在他们想要重新加载图表并再次观看时间流逝时单击“开始”。

现在我的问题是:在我的测试程序中,我总共绘制了大约 500 个值,所以这无论如何都不是一个大数据集。第一次单击 Go 时,所有值都绘制得很好。但是,浏览器的内存使用量猛增(我在 Firefox 和 Chrome 中都试过),当用户再次单击 Go 时,浏览器在绘图过程中完全崩溃了。我完全不知道为什么会发生这种情况——我已经尝试在绘图完成后将所有数组归零,等等。

有人有什么想法吗?这是我的 graph.php 代码,为清楚起见略作修改:

<?php
    #Queries the DB and constructs the data strings assigned to JavaScript arrays below,
    #An example might be: $priceData = '[[0,100.34],[1,108.31],[2,109.40],[3,104.87]]';
?>

<script>
//Global variables used in UpdateGraph():

//The "master" arrays -- I'm just using the same data for all of
//them for now (an array containing around 500 arrays of XY pairs)
var priceDataOrig = <?php echo $priceData; ?>;
var volumeDataOrig = <?php echo $priceData; ?>;
var summaryDataOrig = <?php echo $priceData; ?>;

var priceData = [],
    volumeData = [],
    jsonData = [];
    i = 0,
    pointsToShowAtOnce = 50,
    totalPoints = priceDataOrig.length,
    updateRate = 40;    //milliseconds

UpdateGraph();

//Periodically updates the graph to show time lapse, adding one new point at a time
function UpdateGraph() {
    //Only add a new point if all the points haven't already been added
    if (i != totalPoints) {
        //Add a new point to each array
        priceData.push(priceDataOrig[i]);
        volumeData.push(volumeDataOrig[i]);
        summaryData.push(jsonDataOrig[i]);

        if (i >= pointsToShowAtOnce) {
            //We're showing the amount of points we want to show, so remove the oldest point
            priceData.shift();
            volumeData.shift();
            jsonData.shift();

            //Sets the new X values for these points -- not really pertinent to
            //my question, it works the same if this block is commented out.
            var pLen = priceData.length;
            var j, c = 0;
            for (j = 0; j < pLen; j++) {
                priceData[j][0] = c;
                volumeData[j][0] = c;
                c++;
            }
        }

        //Load the graph itself. 'humblefinance' is just a div on the page.
        HumbleFinance.init('humblefinance', priceData, volumeData, summaryData);

        i++;

        //This function calls itself at the interval in
        //updateRate until all the points have been drawn
        setTimeout('UpdateGraph()', updateRate);
    } else {
        //I null these out here even though it doesn't seem necessary.
        //It doesn't help though.
        priceDataOrig = null;
        volumeDataOrig = null;
        summaryData = null;
        jsonDataOrig = null;
        priceData = null;
        volumeData = null;
        jsonData = null;
    }
}
</script>

<div id="humblefinance"></div>

最佳答案

尝试对 HumbleFinance 进行细微更改。在 init 方法中调用这些函数:

this.buildDOM();
this.attachEventObservers();

这些似乎是您只希望在第一次更新图形时运行的一次性配置函数。似乎创建了很多元素并绑定(bind)了事件,它们会一次又一次地完成,每次都消耗更多内存,因为它们从未被释放。

最简单的方法是在 init 中添加一个参数,这样您就可以有条件地排除这部分,或者将实际绘制图形的代码分离出来作为一个单独的方法。最后,我认为您只希望那些设置过程被调用一次。

关于javascript - 处理数组时可能发生 JavaScript 内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6444963/

相关文章:

javascript - 如何在 angularjs 中按 id 数组对对象列表进行排序?

Java:使用括号初始化整数数组和使用 new 关键字之间的区别

c++ - name\GLOBAL 的句柄什么时候出现??被 build ?

c - 开发过程中的内存泄漏

javascript - 从 knockout 开始

javascript - 测试 navigator.getUserMedia 是否需要 https,无需浏览器用户代理嗅探

javascript - 在 jQuery 执行时删除页面加载 'glitch'

php - 使用循环 PHP、对角线检查增加 IF 语句中的条件

javascript - JS - 理解闭包

wpf - WPF 中的 CollectionViewSource.GetDefaultView() 内存泄漏?