утечка памяти в JavaScript - PullRequest
       0

утечка памяти в JavaScript

7 голосов
/ 05 августа 2011

Я только что заметил, что какой-то написанный мной javascript, похоже, дает утечку памяти, это довольно простой кусок кода - благодаря jquery - но я могу наблюдать за его работой в диспетчере задач, и использование памяти медленно увеличивается от 4 до 40 байтов.

Все, что я делаю, это выбрасываю некоторые данные в контроллер asp mvc / действие через getJSON:

$(document).ready(function () {
    var olddata = "";
    window.setInterval(function () {
        var options = JSON.stringify({
            orderby: "name"
        });
        var params = {
            options: options,
            data: olddata ? JSON.stringify(olddata) : ""
        };
        $.getJSON("/Home/GetTasks", params, function (json) {
            olddata = json;
            json = null;
        });
        params = null;
        options = null;
    }, 1000);
});

Я увеличил значение таймера, чтобы увидеть проблему с большей готовностью. Я, очевидно, что-то делаю не так, но не вижу, что.

Должен ли я очищать вызов getJSON?

ТИА.

1 Ответ

6 голосов
/ 05 августа 2011

Откуда ты знаешь, что у тебя на самом деле утечка памяти?

При небольших числах, таких как 4 и 40 байт, вы могли просто наблюдать рост кучи, но некоторые из новых блоков в куче «свободны» и доступны для будущего использования, поэтому, хотя общее использование памяти приложения увеличивается, память не увеличивается на самом деле не протекает и будет доступен для будущего использования, поэтому он не будет расти вечно.

Если это весь объем вашего эксперимента, то я не вижу проблем с кодом.

Здесь есть три закрытия функций. Закрытие $(document).ready() продлевает срок службы вашего кода, но это разовая сделка, поэтому проблем не должно быть.

Анонимная функция, переданная в setInterval(), поддерживает закрытие $(document).ready(). Каждый вызов анонимной функции setInterval() должен быть новым вызовом, который получит новый набор локальных переменных и освободит его старые, когда предыдущие вызовы завершатся.

Анонимная функция, переданная в getJSON(), создает закрытие для анонимной функции setInterval, но это закрытие должно продолжаться только до тех пор, пока не завершится функция getJSON, и когда она завершит закрытие анонимной функции setInterval(),

Единственное закрытие, которое, как я вижу, длится здесь, это закрытие $(document).ready(), которое вы намереваетесь создать, и оно создается только один раз, поэтому оно не должно вызывать утечки.

Все локальные переменные в анонимной функции getJSON будут освобождены после ее завершения. Единственные данные из сохранившегося вызова getJSON - это ваше назначение:

olddata = json;

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

Здесь нет манипуляций с DOM, поэтому нет возможности для перекрестных или циклических ссылок между DOM и JS.

Мой вывод таков: я не вижу ничего, что могло бы протечь. Я вижу множество вещей, использующих временную память, поэтому я подозреваю, что то, что вы видите при использовании памяти процесса, это просто рост кучи, но рост таким образом, что объем памяти, который в конечном итоге будет использоваться, будет в конечном итоге использован повторно. Если браузер также кэширует результаты JSON, возможно, вы также заметили увеличение кеша памяти.

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

Отказ от ответственности: один отказ от ответственности здесь заключается в том, что я предполагаю, что функция jQuery $.getJSON() не протекает сама по себе и всегда завершается способом, который очищает создаваемое замыкание, даже если вызов ajax не выполнен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...