【问题标题】:nvd3 application memory leaknvd3 应用程序内存泄漏
【发布时间】:2016-03-28 21:45:53
【问题描述】:

我有一个经常更新的动态折线图,请参阅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 后,内存消耗看起来“不错”... 但是几分钟后有人饿了,吃了我的字节......

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

【问题讨论】:

标签: javascript d3.js memory-leaks nvd3.js


【解决方案1】:

我让你在其中一个 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 function 中,仅当窗口处于焦点时才更新图表:

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();

        }

工作代码here

希望这会有所帮助!

【讨论】:

  • 我刚刚使用 IE11 尝试了您的 jsfiddle,15 分钟后总内存达到 3.6 GB - 仍在增长...在此期间图表被另一个选项卡隐藏。 (很遗憾,我无法在此评论中添加屏幕截图)
  • 好吧,不幸的是我没有 IE ...所以,如果您在运行此 jsfiddle.net/y3d5wdof/1 并将焦点更改为其他选项卡时可以看到“未调用”,您能否在控制台中检查
  • 对不起,试试这个小提琴jsfiddle.net/cyril123/y3d5wdof/3,看看它是否有效!
  • 好的,“调用”和“未调用”出现。我可以看到它停止了。为了方便用户,我会检查一下并尝试“不可见”之类的东西。
  • 是的!这个想法是,当标签不在焦点中时,图表不会更新......当它获得重点时,它开始绘图。 span>
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 2010-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-05
    • 2019-01-26
    • 2012-06-16
    相关资源
    最近更新 更多