Задать вопрос
karabanov
@karabanov
Системный администратор

JS-скрипт. Утечка памяти. Как исправить?

Привет.
Я вывожу логи с коммутаторов в окно браузера (этакий tail -F только в браузере). И всё даже работает:

2b343250594e45d99a416e727ba08044.png
Но с течением времени память заканчивается, SWAP растёт, компьютер начинает дико тормозить.
Вот так выглядит скрипт:
// Функция, которая проверяет нет ли в логе новых записей
  function updateLog()
  {
    $.getJSON('PHPTail.php?ajax=1&lastsize=' + lastSize + '&grep=' + grep,

    function(data) { lastSize = data.size;

    $.each(data.data, function(key, value)
    {
      // Выводим данные в соответствующий блок
      $("#results").append(value);
         delete data;
     }); 
  });
}

// Функция, которая удаляет старые записи
function removeOld()
{
  // Когда записей становиться моного стираем лишние
  if($(".line").length > 300) { $("#results .line:first").remove(); }
}

// Вызываем функцию, которая проверит нет ли в логе новых записей
var timerId = setTimeout(function tick() {
  updateLog();
  timerId = setTimeout(tick, 1600);
}, 1600);

// Вызываем функцию, которая удалит старые записи
var timerIdd = setTimeout(function tick() {
  removeOld();
  timerIdd = setTimeout(tick, 10000);
}, 10000);


Подозреваю, что функция removeOld() работает неправильно, либо вообще не работает. Как её заставить работать правильно?
  • Вопрос задан
  • 521 просмотр
Подписаться 2 Оценить 2 комментария
Решения вопроса 1
Lynn
@Lynn
nginx, js, css
Судя по коду, когда у вас больше 300 сообщений вы удаляете только одно, что довольно странно.

Ещё вместо setTimeout можно (и нужно) использовать setInterval.

function removeOld() {
  // Удаляем всё кроме последних трёхсот элементов.
  $(".line").slice(0, -300).remove();
}

setInterval(updateLog, 1600);
setInterval(removeOld, 10000);
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
byte916
@byte916
Скорее всего утечка памяти при создании таймера.
Дело в том, что функция, созданная в таймере, не удаляется пока она не завершена. У вас она рекурсивно создаёт таймер для себя при каждом тике, и вследствие замыкания тянет за собой уже устаревшие и не нужные данные. Скорее всего, нужно копать в эту сторону, например использовать setInterval
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы