5

我每秒都根据新数据重新绘制图表,它工作得很好,看起来很棒,但我注意到它每秒增加 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)
4

2 回答 2

6

我已经通过全局存储图表解决了这个问题。在绘制图表之前,您需要检查图表是否已经实例化。如果没有,则创建新的图表对象,否则在绘制之前调用 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);
}
于 2014-08-01T12:17:15.457 回答
3

有同样的问题,可以通过在谷歌的 clearChart() 函数中添加几行来解决它。

W.clearChart = function() {

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

    ...
};

更多细节:

  1. 这是我进行更改的 Google 文件:

https://www.google.com/uds/api/visualization/1.0/4086f2e8fc632adc52e6d6795a5637a4/format+en,default,corechart.I.js

  1. 下载此文件,进行上述更改。在您的代码中,添加一个脚本标签以从您的网络服务器加载上述文件并注释掉以下行:

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

  2. 内存会上升,但几分钟后会自行恢复。

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

  4. 这是一个测试页面(1.js 是第 1 步中修改后的文件)。它基本上创建新图表并每 100 毫秒重绘一次。您会看到内存增加,但点击“停止”链接停止重绘并等待几分钟,内存就会减少。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.js"      type="text/javascript"></script>
  <script src="https://www.google.com/jsapi"                                          type="text/javascript"></script>

  <script src="1.js"                                          type="text/javascript"></script>


  <script type="text/javascript">

      //init google charts
//        google.load('visualization', '1', { packages: ['corechart'] });
      google.load('visualization', '1', { packages: ['table'] });

  </script>


</head>
<body>

<a href='#' onclick='stop()'>Stop</a>
  <div class='chart'></div>

  <script>

      var chart; var table;

      function createChart(container)
      {
          if(chart != undefined)
              chart.clearChart();

          //init chart
          chart = new google.visualization.LineChart(container[0]);

          //init chart data
          if(table == undefined)
          {
              table = new google.visualization.DataTable();

              table.addColumn('datetime', 'Time');
              table.addColumn('number', 'Value');

              var count = 0;

              //periodically add rows
              setInterval(function()
              {
                  //add row
                  table.addRows([ [new Date(), count++]]);    
              }, 1000);


          }
      }


      //start redrawing
      var id = setInterval(function()
      {
          createChart($('.chart'));

          drawChart();
      }, 100);

      //stop redrawing
      function stop()
      {
          clearInterval(id);
      }

      //draw chart
      function drawChart()
      {
          chart.draw(table, { curveType: "function",

              width:      250, 
              height:     250,
              pointSize:  1,
              legend:     { position: 'none' },
              chartArea: { 'width': '90%', left: 50 },
          });
      }

  </script>   
</body>
</html>
于 2013-09-17T01:09:04.943 回答