Javascript 谷歌图表不断重画内存增加

Javascript 谷歌图表不断重画内存增加,javascript,google-visualization,Javascript,Google Visualization,我每秒根据新数据重新绘制图表,它工作正常,看起来很棒,但我注意到它增加了内存,就像每秒1 MB的使用量。有办法解决这个问题吗?我注意到,如果我只有静态图表,那么内存就会稳定下来,但是一旦我添加了不断的重画(为了更新数据),内存的使用就永远不会停止 起初,我认为这是因为我每次都在创建一个新的图表实例,所以我修改了代码,使它每次只重新绘制同一个实例,但这一点帮助不大 有人知道怎么修吗?我需要先把旧的图表倒出来吗 google.setOnLoadCallback(test); var chart;

我每秒根据新数据重新绘制图表,它工作正常,看起来很棒,但我注意到它增加了内存,就像每秒1 MB的使用量。有办法解决这个问题吗?我注意到,如果我只有静态图表,那么内存就会稳定下来,但是一旦我添加了不断的重画(为了更新数据),内存的使用就永远不会停止

起初,我认为这是因为我每次都在创建一个新的图表实例,所以我修改了代码,使它每次只重新绘制同一个实例,但这一点帮助不大

有人知道怎么修吗?我需要先把旧的图表倒出来吗

google.setOnLoadCallback(test);

var chart;
var chartOptions;
var chartCreate;

function test() {
    chart = new google.visualization.DataTable();
    chart.addColumn('string', 'Lorem');
    chart.addColumn('number', 'Ipsum');
    chart.addRows([
            ['', 0]
    ]);
    chartOptions = {};
    chartCreate = new google.visualization.LineChart(document.getElementById('chartDiv'));
          chartCreate.draw(chart, chartOptions);
    ]);
}

function test2() {
    chart.removeRows(0, 5);
    for (var i = 0; i < dataSpaceArray.length; ++i) {
        chart.addRow([dataTimeArray[i], dataSpaceArray[i], dataSpeedArray[i]]);
    }
        chartCreate.draw(chart, chartOptions);
}

setTimeout(test2,1000)
google.setOnLoadCallback(测试);
var图;
var期权;
var图表创建;
功能测试(){
chart=新的google.visualization.DataTable();
chart.addColumn('string','Lorem');
图表.addColumn('number','Ipsum');
chart.addRows([
['', 0]
]);
图表选项={};
chartCreate=newgoogle.visualization.LineChart(document.getElementById('chartDiv');
chartCreate.draw(图表、图表选项);
]);
}
函数test2(){
图1.1(0,5);
对于(var i=0;i
也有同样的问题,通过在Google的clearChart()函数中添加几行代码就可以解决

W.clearChart = function() {

    //this fixes the leak
    hv = {};
    iv = {};
    jv = {};

    ...
};
更多详情:

  • 这是我更改的谷歌文件:
  • 下载此文件,进行上述更改。在代码中,添加脚本标记以从Web服务器加载上述文件,并注释掉以下行:

    //load('visualization','1',{packages:['corechart']})

  • 内存会上升,但几分钟后会自行下降

  • 我使用的是clearChart(),但如果您不想清除图表,请创建自己的函数(例如memoryLeakFix()),并定期调用它

  • 这是一个测试页面(1.js是步骤1中修改过的文件)。它基本上会创建新图表,并每100毫秒重新绘制一次。您将看到内存上升,但点击“停止”链接停止重画并等待几分钟,内存将下降

  • 
    //初始化谷歌图表
    //load('visualization','1',{packages:['corechart']});
    load('visualization','1',{packages:['table']});
    var图;var表;
    函数createChart(容器)
    {
    如果(图表!=未定义)
    chart.clearChart();
    //初始图
    chart=新的google.visualization.LineChart(容器[0]);
    //初始图表数据
    如果(表==未定义)
    {
    table=新的google.visualization.DataTable();
    table.addColumn('datetime','Time');
    表.addColumn('number','Value');
    var计数=0;
    //定期添加行
    setInterval(函数()
    {
    //添加行
    table.addRows([[new Date(),count++]);
    }, 1000);
    }
    }
    //开始重画
    var id=setInterval(函数()
    {
    createChart($('.chart'));
    图纸();
    }, 100);
    //停止重画
    函数停止()
    {
    清除间隔(id);
    }
    //绘制图表
    函数绘图图()
    {
    draw(表,{curveType:“函数”,
    宽度:250,
    身高:250,
    点大小:1,
    图例:{位置:'无'},
    图表区:{“宽度”:“90%”,左:50},
    });
    }
    

    我通过全球存储图表解决了这个问题。在绘制图表之前,您需要检查图表是否已实例化。如果没有,请创建新的图表对象,否则请在绘制之前调用clearChart()方法。像这样:

    //Store all chart objects in a global array to avoid memory leak
    var charts = [];
    
    function drawChart(chartName, element, data, chartOptions) {
       if (charts[chartName] === undefined || charts[chartName] === null) {
              charts[chartName] = new google.visualization.LineChart(group);
       } else {
              charts[chartName].clearChart();
       }
       charts[chartName].draw(dataTable, chartOptions);
    }
    

    重画时的内存泄漏是一个已知问题。据我所知,你对此无能为力。可视化API开发团队知道并正在研究它。你有什么来源吗?这看起来真的很奇怪,它几乎意味着你不能更新图表中的数据。仅供参考,最新的候选版本(load v1.1而不是v1)包括一些内存泄漏问题的修复程序。当你调用
    google.load('visualization','1',{packages:[/*packages list*/],callback:drawChart})
    ,将
    1
    替换为
    1.1
    。好的,谢谢!对于1.1,泄漏(如有)可忽略不计。但总体消耗量更高(从约7MB增加到约15MB)。在pc上工作,但在Raspberry Pi上非常缓慢(另一个故事:-)。你应该考虑1.1个对这个问题的好答案!我可以看出你令人印象深刻的黑客可以避免一些内存泄漏。但人们应该意识到,这在几个方面是脆弱的。当与其他重用图表的方法一起使用时,特别是在仪表板中,可能会出现复杂情况。此外,创建库的新版本时,类和内部变量的编译名称可能会有所不同。但希望新版本能够修复这些内存泄漏。确认这是可行的,但在clearChart之后,我不得不再次实例化——新的google.visualization.LineChart(group);
    //Store all chart objects in a global array to avoid memory leak
    var charts = [];
    
    function drawChart(chartName, element, data, chartOptions) {
       if (charts[chartName] === undefined || charts[chartName] === null) {
              charts[chartName] = new google.visualization.LineChart(group);
       } else {
              charts[chartName].clearChart();
       }
       charts[chartName].draw(dataTable, chartOptions);
    }