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

同じ問題があり、Google の 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. このファイルをダウンロードし、上記の変更を行います。コードに、web サーバーから上記のファイルをロードするスクリプト タグを追加し、次の行をコメント アウトします。

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

  2. メモリは上がりますが、数分後に自然に元に戻ります。

  3. 私は clearChart() を使用していますが、チャートをクリアしたくない場合は、独自の関数 (例: memoryLeakFix()) を作成し、定期的に呼び出します。

  4. これがテスト ページです (1.js はステップ 1 で変更されたファイルです)。基本的に、新しいチャートを作成し、100ms ごとに再描画します。メモリが増加するのを確認できますが、[停止] リンクをクリックして再描画を停止し、数分待つとメモリが減少します。

<!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 に答える