ng-grid 和实时数据内存泄漏

Posted

技术标签:

【中文标题】ng-grid 和实时数据内存泄漏【英文标题】:ng-grid and real-time data memory leak 【发布时间】:2014-02-27 17:59:27 【问题描述】:

我正在尝试使用 ng-grid 来可视化高频实时数据,但我遇到了内存泄漏问题。当我使用带有 ng-repeat 的简单 html 表时,不存在内存泄漏。

我在后端使用 node+express,在客户端使用 angularjs。 我使用 socket.io 将实时数据从服务器流式传输到客户端的表中。

我在一个简化的例子中重现了内存问题:

我每秒发送 1500 条消息,每条消息都是一个像这样的对象 id:1,名称:“名称”,时间:“[当前日期/时间字符串]” 4 分钟后浏览器内存超过 400MiB,10 分钟后超过 1GiB

我已经在 Chrome 和 Firefox 上进行了测试。

这是简化的示例,我做错了吗? (最后添加的附加信息)。

服务器

var app = express();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
io.of('/test').on('connection',  function (socket) 

    console.log('socket connection: /test');

    for (id=1; id<16; id++) 
        streamData(id);
    

    function streamData(id) 
      setInterval(function () 
        socket.emit('updateData', 
            id: id, 
            name: "test"+id, 
            time: (new Date()).toString()
        );
      , 10);
    
);

服务使用angular-socket-io

factory('testSocket', function(socketFactory) 
    return socketFactory(
        iosocket:  io.connect('http://localhost/test')
    );
)

控制器

controller('NgGridTestCtrl', function ($scope, testSocket)      
  var itemsObj = ;
  $scope.items = [];
  $scope.gridOptions =  
      data: 'items',
      columnDefs: [field:'id', displayName:'ID', width:'15%', 
                   field:'name', displayName:'Name', width:'20%',
                   field:'time', displayName:'Date and Time', width:'65%'],
      enableColumnResize: true    
  ;

  testSocket.on('updateData', function(data) 
      itemsObj[data.id] = data;
      var values = [];
      angular.forEach(itemsObj, function(value, index) 
          this.push(value);
      , values);

      // the data for ng-grid
      $scope.items = values;
  );

);

ngGrid 模板

<div>
   <h1>ng-grid table</h1>
   <div class="gridStyle" ng-grid="gridOptions"></div>   
</div>

已编辑以添加普通表格示例

使用普通表没有内存问题,浏览器内存保持在 155MiB 左右

控制器

  controller('SimpleTableCtrl', function ($scope, testSocket) 
     $scope.items = ;
      testSocket.on('updateData', function(data) 
          $scope.items[data.id] = data;
      );      
  ).

普通表格模板

<div>
  <h1>Simple table with ng-repeat</h1>
  <table class="table">
    <thead>
      <tr>
        <th>ID</th>
        <th>Name</th>
        <th>Time</th>
      </tr>
    </thead>
    <tbody>
      <tr ng-repeat="item in items">
        <td>item.id</td>
        <td>item.name</td>
        <td>item.time</td>
      </tr>
    </tbody>
  </table>

补充意见

    内存问题不仅仅与 ng-grid 有关;它还使用带有 ng-repeat 的“普通表模板”的“NgGridTestCtrl”控制器来表现自己。 如果数据的频率较低(500 毫秒而不是 streamData 函数中的 10 毫秒间隔),内存问题不会表现出来(使用 ng-grid 模板和 NgGridTestCtrl)。 内存问题仍然存在,(使用普通表格模板和 NgGridCtrl),如果数据的频率较低,(500 毫秒而不是 streamData 函数中的 10 毫秒间隔)。正如人们所预料的那样,内存只是以较慢的速度增长。 使用带有“普通表格模板”的“SimpleTableCtrl”时,较高频率的数据不会导致内存问题。 我还不能将 ng-grid 用于更高频率的数据。有人知道 ng-grid 是否真的可以处理高频数据吗?

【问题讨论】:

嘿,你解决过这个问题吗?表现如何? @parliament 不,我现在使用的是普通表,我没有内存问题。你对 ng-grid 有同样的问题吗? 我现在正在为它构建一个 signalR 测试工具,会告诉你的。但是,我不确定我可以说您的示例是内存泄漏,因为您正在将 1500 条消息/秒加载到内存中。为什么不增加? 我确实注意到打印 gridOptions 表明 ng-grid 将数据存储在内存中 3 次。奇怪地在这里github.com/angular-ui/ng-grid/issues/1021 发布了一个关于它的问题。因此,在您的示例中,实际上将 4500 msg/sec 加载到内存中 @parliament ng-grid 的问题是内存不断增长,从未达到饱和值。为了比较,我用普通表显示相同的数据,这没有内存问题,内存设置为大约 150MiB。 【参考方案1】:

嗨,我认为首先你需要找到你的内存泄漏在哪里。为此,您可以在 Chrome 中使用“堆分配”:

F12 -> 配置文件 -> 记录堆分配。

这里是主题:

Object allocation tracking

【讨论】:

以上是关于ng-grid 和实时数据内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

历年沪深A股香港H股票数据导入和实时数据更新展示 ---转载

容器和实时资源监控的必知要素

身份验证和实时数据库同时进行?

Kafka+Storm+HDFS整合实践

从服务器更新后刷新 ng-grid 时出现空白数据

50000字,数仓建设保姆级教程,离线和实时一网打尽(理论+实战) 下