Утечка памяти приложения nvd3

У меня есть живая линейная строка, которая часто обновляется, см. 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();
  }
}

Запуск этого js в IE11 с помощью "средств разработки" "Общая память" сначала немного увеличивается, но через несколько минут он начинает быстро расти.

После запуска jsfiddle потребление памяти выглядит "хорошо"... после запуска но через несколько минут кто-то проголодался и ест мои байты... начать есть память

Кто-нибудь знает, что я делаю неправильно?

Ответ 1

Я заставлял вас играть в течение 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();

        }

Рабочий код здесь

Надеюсь, это поможет!

Ответ 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);
}