Браузеры продолжают хранить память с помощью AJAX + setInterval

Мне нужно обновить много данных в течение заданного интервала с помощью JavaScript. Проблема в том, что независимо от того, какую библиотеку JS я использую (даже bare-bone js), что все браузеры, по-видимому, выделяют память на каждый запрос AJAX и впоследствии не могут ее освободить. Вот образец, который должен быть воспроизведен, чтобы воспроизвести ошибку:

    <!DOCTYPE html>
    <html lang="en">
        <head>
            <title>Memleak Test</title>
            <meta charset="utf-8" />
            <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
            <script type="text/javascript">

                function readData() {
                    $.getJSON('data.php');
                }

                $(document).ready(function() {
                    setInterval(readData, 1000);
                });
            </script>
        </head>
        <body>
            <div id="content"></div>
        </body>
    </html>

Эквивалентная тестовая страница доступна по адресу jsbin

Подробнее об этом:

  • Я также попытался поместить функцию readData() в качестве замыкания непосредственно в вызове setInterval(). Это, похоже, не имеет никакого значения.
  • Здесь я использую jQuery, но любая другая библиотека будет вызывать те же ошибки.
  • My data.php script просто создает поддельный JSON-Object с json_encode() в PHP.
  • Я знаю, что одна секунда - короткий таймфрейм здесь, в моей работе script таймфрейм составляет 30 секунд. Я просто хотел увидеть эффект быстрее (в рабочем приложении требуется несколько часов, но затем память тоже заполнена).
  • Проблема в том, что приложение будет открыто 24/7.

Кажется, так просто, что я думаю, что я делаю что-то действительно не так, было бы здорово, если бы некоторые из гуру JS здесь могли мне помочь!

Ответы

Ответ 1

Одна из возможных проблем с тем же самым сообщением заключается в том, что , если запросы XHR занимают больше времени, чем период опроса (в среднем), будет возрастать очередь ожидающих запросов. Если сам веб-сервер начинает запросы на отставание, это может превратиться в порочный круг.

Чтобы избежать этого возможного случая, используйте кодировку в стиле CPS, где следующее действие выполняется с использованием соответствующих обратных вызовов. То есть, не запускайте следующий запрос до тех пор, пока не потребуется (предыдущий запрос завершен: успех или сбой). Этот подход все еще может использоваться для создания очереди запросов вручную с контролируемым размером, если требуются многочисленные невыполненные запросы.

Кроме того, убедитесь, что неиспользуемые объекты имеют право на рекультивацию, поскольку это "стандартная" причина "утечки памяти" на языке GC.

Счастливое кодирование.


Код в сообщении не содержит ничего, что по своей сути будет утечка памяти. Это может быть проблемой внутри с jQuery, но это всего лишь предположение. Кроме того, такие инструменты, как Firebug, которые отслеживают XHR/веб-запросы, могут потреблять значительное количество памяти, поэтому нужно что-то проверить и убедиться, что поведение не является Гейзенбергом.


Кроме того, помните, что увеличение использования памяти не указывает на утечку памяти, если она не становится неограниченной. Цикл сбора мусора будет возникать только тогда, когда хосты чувствуют себя так.

Ответ 2

Просто подумайте, вместо setInterval вы должны использовать setTimeout, а затем, когда он истечет, вы снова установите таймаут.

Таким образом, вы не рискуете запуском setInterval, если по какой-то причине вы потеряете его:

Я также думаю, что jquery ajax имеет успешный обратный вызов, который вы можете использовать в качестве точки, которую вы задали для Timeout. Таким образом, как уже упоминалось в этом потоке в другом месте, вы не заканчиваете перекрывающиеся запросы.

(только что проверено и есть обратный вызов успеха)

Ответ 3

вы проверяете каждую секунду. Определенно, он будет потреблять всю память. Что вы можете сделать, так это установить предопределенный интервал. Затем после опроса, если данные доступны, извлеките это и сохраните интервал таким же образом, но если после опроса данных пока нет, увеличьте интервал, чтобы убедиться, что следующий опрос задерживается. Таким образом вы можете уменьшить нагрузку.

Ответ 4

Взгляните на это сообщение - может помочь?

Как я могу заставить мусорную корзину Javascript в IE? IE работает очень медленно после вызовов AJAX и манипуляций с DOM

(Предлагает использовать определенные методы JQuery, которые, по-видимому, пытаются избежать утечек памяти: и используя команду "удалить", чтобы попытаться освободить место).

Ответ 6

Согласно этот поток форума jQuery:

...
success: function(data) {

    // the line below prevents the leak, apparently
    document.getElementById("theContainer").innerHTML = ""; 
    $("#theContainer").html(data);
}

Ответ 7

Вы пытались повторно использовать переменные внутри своих вызовов? Значение вместо того, чтобы создавать новые переменные, где вы обрабатываете ответ, просто используйте те же самые. Скажите

window.myvar = response["myvar"];

Это действительно утечка, это может помочь сборщику мусора. Было бы неплохо увидеть фактический код того, что вы делаете.