Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
处理数组时可能存在JavaScript内存泄漏?_Javascript_Arrays_Memory Leaks_Google Finance - Fatal编程技术网

处理数组时可能存在JavaScript内存泄漏?

处理数组时可能存在JavaScript内存泄漏?,javascript,arrays,memory-leaks,google-finance,Javascript,Arrays,Memory Leaks,Google Finance,我用它一次一点地绘制一系列数据,以实现延时效果。我的代码如下,但我想先解释一下: 如果您不熟悉HF,那么它的初始化函数将使用三个JavaScript数组(priceData、volumeData和summaryData),然后将这些数组绘制到三个图形上。这些阵列每个都包含若干XY对阵列 在我的程序中,我声明了三个空的“图形”数组(priceData、volumeData和summaryData),然后从数据库中获取值,并将它们放入名为priceDataOrig、VolumeDataRig和sum

我用它一次一点地绘制一系列数据,以实现延时效果。我的代码如下,但我想先解释一下:

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

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

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

现在我的问题是:在我的测试程序中,我总共绘制了大约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>

//UpdateGraph()中使用的全局变量:
//“主”数组——我只是对所有的数组使用相同的数据
//目前它们(一个包含大约500个XY对数组的数组)
var priceDataOrig=;
var volumeDataOrig=;
var summaryDataOrig=;
var priceData=[],
体积数据=[],
jsonData=[];
i=0,
点STOSHOWATONCE=50,
totalPoints=priceDataOrig.length,
updateRate=40;//毫秒
UpdateGraph();
//定期更新图表以显示时间推移,每次添加一个新点
函数UpdateGraph(){
//仅在尚未添加所有点的情况下添加新点
如果(i!=总分){
//向每个阵列添加一个新点
priceData.push(priceDataOrig[i]);
体积数据推送(体积数据推送[i]);
summaryData.push(jsonDataOrig[i]);
如果(i>=pointsToShowAtOnce){
//我们正在显示要显示的点数,因此请删除最旧的点数
priceData.shift();
volumeData.shift();
jsonData.shift();
//为这些点设置新的X值——与
//我的问题是,如果这个块被注释掉,它的工作原理是一样的。
var pLen=priceData.length;
var j,c=0;
对于(j=0;j
2个想法

1-调试器有时会导致内存泄漏。firebug/devtools关闭时是否会发生这种情况

2-快速浏览HumbleFinance.js的代码,看起来这些图是附加到容器中的,而不是替换容器中的内容。在调用init之前,这样做可能会有所帮助:

$('#humbledata')[0].innerHTML = ''

或者jQuery希望您如何做这些事情。

尝试对HumbleFinance做一点小改动。在init方法中,这些函数被调用:

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


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

我不确定,但它可能会在setTimeout('UpdateGraph()之后发生,updateRate);正在从函数内部调用。如果我没有弄错(我可能是XD)只要函数正在使用,JS就不会删除内存。你应该在页面加载时设置超时,而不是在函数内部设置。AFAIK除非函数自己调用,否则无法确保函数每40毫秒调用一次。我遇到的问题是在多次运行整个时间间隔后,将脚本重新加载到内存中每次都会调用div。因此,JS似乎在重新加载graph.php之后仍在继续使用内存。我同意,没有办法确保函数每隔40毫秒调用一次,速度较慢