nvd3 应用程序内存泄漏

14

我有一个实时更新的折线图,可以查看http://jsfiddle.net/cddw17fg/5/

function redraw() {
  if (!redraw.isGraphShown) {
    redraw.isGraphShown = true;
    ...
  } else {
    d3.select('#chart svg')
      .datum(data)
      .transition().duration(1500)
      .call(chart);

    d3.select('.nv-x.nv-axis > g').selectAll('g').selectAll('text')
      .attr('transform', function(d, i, j) {
      return 'translate (-40, 40) rotate(315)'
    });
    nv.tooltip.cleanup();
    chart.update();
  }
}

在IE11中使用“开发工具”运行此js,首先“总内存”会略微增加,但几分钟后它开始快速增长。

启动jsfiddle后,内存消耗看起来很“好”... after startup 但是几分钟后,有人会感到饥饿并吃掉我的字节... starting to eat memory

有人知道我做错了什么吗?


1
尝试使用最新的1.8.1版本在http://jsfiddle.net/3va0m0e4/2/上,看起来在Chrome中出现了相同的问题。 - Osman Mazinov
2个回答

2

我在做其他事情时,让你的小提琴在一个Chrome标签页上运行了30分钟,结果它崩溃了。

然而,如果我保持标签页打开,并且该标签页从未失去焦点,它就不会崩溃,并且可以无缝地继续工作。

因此,我认为nvd3不会更新图表,而是在模糊状态下将所有更新保存在集合中,这就是为什么内存不断增加的原因。现在,当重新聚焦在标签页上时,它尝试呈现所有更新,屏幕冻结并最终崩溃。

现在,作为解决方法:

我正在使用JQUERY检测窗口是否聚焦:

$(window).focus(function() {
    window_focus = true;//set this flag on
}).blur(function() {
    window_focus = false;//set this flag off as window is not in display
});

现在,在您的redraw函数中,只有窗口处于焦点状态时才进行图表更新:
if(window_focus){
            chart.update();
            d3.select('#chart svg')
                .datum(data)
                //.transition().duration(1500)
                .call(chart);

            d3.select('.nv-x.nv-axis > g').selectAll('g').selectAll('text')
                .attr('transform', function(d, i, j) {
                    return 'translate (-40, 40) rotate(315)'
                });
            nv.tooltip.cleanup();

        }

这里有可运行的代码,点击这里

希望这能帮到你!


我刚刚使用IE11尝试了你的jsfiddle,在15分钟后我达到了3.6GB的总内存 - 仍在增长...此期间图表被另一个选项卡隐藏了。(不幸的是,我无法将截图添加到此评论中) - Mario
好的,不幸的是我没有IE浏览器...所以你能否在控制台中检查一下,当你运行这个http://jsfiddle.net/y3d5wdof/1/并将焦点更改到其他选项卡时,是否可以看到“未调用”? - Cyril Cherian
抱歉,请使用此代码片段 http://jsfiddle.net/cyril123/y3d5wdof/3/,看看是否有效! - Cyril Cherian
是的!这个想法是当选项卡不在焦点时,图表不会更新...当它获得焦点时开始绘制。 - Cyril Cherian
我的测试显示现在好多了,但是我仍然有越来越多的对象挂起。似乎每次图表失去焦点并重新获得焦点时都会丢失一些东西。不幸的是... - Mario
显示剩余3条评论

0

这似乎是NVD3或D3本身的一个bug。我现在的解决方法是每10分钟重新加载带有图表的页面。

var startDateNVD3Reload = Date.now();
...
var elapsed_time_minutes = (Date.now() - startDateNVD3Reload)/1000/60;
if (elapsed_time_minutes > 10)
{
    location.reload(true);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接