Утечка памяти при вытягивании JSON из WEB

Я потратил дни на это и ударил его со всех сторон, о которых я могу думать. Я работаю над простым гаджетом Windows 7. Этот script будет вытаскивать данные JSON с удаленного веб-сервера и помещать их на страницу. Я использую jQuery 1.6.2 для $.getJSON. script потребляет больше памяти для каждого цикла.

var count = 1;

$(document).ready(function () {
    updateView();
});

function updateView(){
    $("#junk").html(count);
    count++;
    $.getJSON( URL + "&callback=?", populateView);
    setTimeout( updateView, 1000 );
}

function populateView(status) {
    $("#debug").html(status.queue.mbleft + " MB Remaining<br>" + status.queue.mb + " MB Total");
}

Любая помощь будет принята с благодарностью.... Спасибо!

EDIT: Добавить образец данных JSON

?({"queue":{"active_lang":"en","paused":true,"session":"39ad74939e89e6408f98998adfbae1e2","restart_req":false,"power_options":true,"slots":[{"status":"Queued","index":0,"eta":"unknown","missing":0,"avg_age":"2d","script":"None","msgid":"","verbosity":"","mb":"8949.88","sizeleft":"976 MB","filename":"TestFile#1","priority":"Normal","cat":"*","mbleft":"975.75","timeleft":"0:00:00","percentage":"89","nzo_id":"-n3c6z","unpackopts":"3","size":"8.7 GB"}],"speed":"0  ","helpuri":"","size":"8.7 GB","uptime":"2d","refresh_rate":"","limit":0,"isverbose":false,"start":0,"version":"0.6.5","new_rel_url":"","diskspacetotal2":"931.51","color_scheme":"gold","diskspacetotal1":"931.51","nt":true,"status":"Paused","last_warning":"","have_warnings":"0","cache_art":"0","sizeleft":"976 MB","finishaction":null,"paused_all":false,"cache_size":"0 B","finish":0,"new_release":"","pause_int":"0","mbleft":"975.75","diskspace1":"668.52","scripts":[],"categories":["*"],"darwin":false,"timeleft":"0:00:00","mb":"8949.88","noofslots":1,"nbDetails":false,"eta":"unknown","quota":"","loadavg":"","cache_max":"0","kbpersec":"0.00","speedlimit":"","webdir":"","queue_details":"0","diskspace2":"668.52"}})

РЕДАКТИРОВАТЬ 2: Разделенный код до этого, и он все еще протекает. Я думаю, что исключает возможность перемещения DOM в качестве вкладчика.

$(document).ready(function () {
    setInterval(updateView, 1000);
});

function updateView(){
    $.getJSON( URL + "&callback=?", populateView);
}

function populateView(status) {
}

РЕДАКТИРОВАТЬ 3: Это не jQuery. Я удалил jQuery и сделал это с помощью прямых js. Все еще течет.

function init(){
    setInterval(updateView, 1000);
}

function updateView(){
    var xhr = new XMLHttpRequest();
    xhr.open("GET", URL, false);
    xhr.setRequestHeader( "If-Modified-Since", "0");
    xhr.send('');
}

Итак... если это не jQuery, не только в IE (Chrome тоже). Какого черта?! Идеи?

Спасибо!

Ответ 1

Изменить 2:

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

Если вы можете воссоздать свой script в небольшом html файле, вы можете запустить этот инструмент и посмотреть, работает ли он IE:

http://blogs.msdn.com/b/gpde/archive/2009/08/03/javascript-memory-leak-detector-v2.aspx

Кроме того, вы используете IE8 или 9?


Edit:

На основе строки JSON в Op; в основном проблема вводит в заблуждение. бит javascript опубликовал работает отлично.

Сервер, создающий JSON, является тем, который показывает разницу в использовании памяти, я бы исследовал веб-сайт/конечную точку, которые создают этот JSON и видят, что проблема.


Просто подумал,

$. getJSON - это только сокращенная функция для вызова jQuery $.ajax.

Интересно, изменилось ли это, если вы изменили свой код на использование $.ajax, но специально добавили к нему механизм кэширования:

$.ajax({
  url: URL + "&callback=?",
  dataType: 'json',
  cache: false,
  success: populateView
});

Это может помешать попытке сохранить его в памяти, возможно, и в зависимости от вашего браузера он может отображать больше памяти, потому что у вас просто не было сбора мусора, так сказать.

Ответ 2

У меня такое ощущение, что функция setTimeout в updateView вызывает такое поведение. Чтобы проверить это, вы можете изменить свой код на:

$(document).ready(function () {
   setInterval(updateView, 1000);
});

function updateView(){
    $("#junk").html(count);
    count++;
    $.getJSON( URL + "&callback=?", populateView);
}

function populateView(status) {
    $("#debug").html(status.queue.mbleft + " MB Remaining<br>" + status.queue.mb + " MB Total");
}

EDIT: функция setInterval будет выполнять переданную функцию снова и снова каждые x миллисекунд. Здесь в документах.

ИЗМЕНИТЬ 2: Еще одна производительность (хотя это может и не быть критическим для этой проблемы) заключается в том, что вы пересекаете DOM каждую секунду, чтобы найти элемент $('#debug'). Вы можете сохранить это и передать его как:

        $(document).ready(function () {
            var debug = $('#debug'); 
            var junk = $('#junk')          ;
            setInterval(function(){updateView(debug, junk)}, 1000);

        });

        function updateView(debug, junk){
           junk.html(count);
            count++;
            $.getJSON( URL + "&callback=?", function(status){populateView(status,debug)});
        }

        function populateView(status) {
            debug.html(status.queue.mbleft + " MB Remaining<br>" + status.queue.mb + " MB Total");
        }

Изменить 3: я изменил код выше, потому что забыл взять ответ с сервера. Предполагая, что queue является свойством возвращенного JSON, тогда код должен быть таким, как указано выше.

Редактировать 4: Это очень интересная проблема. Тогда другой подход. Предположим тогда, что все еще есть некоторые скрипты на стороне клиента, которые забивают память. Что бы это могло быть? Насколько я понимаю, осталось только две вещи: setInterval и функция $.getJSON. Функция $.getJSON - это простая оболочка запроса ajax, которая запускает запрос и ожидает ответа от сервера. Функция setInterval является немного более своеобразной, поскольку она будет настраивать таймеры, функции огня и т.д.

Я думаю, если вам удастся имитировать это на своем сервере или даже просто обновить эту веб-страницу в браузере каждую секунду /5 секунд, вы сможете увидеть, обрабатывает ли клиент или сервер ваш запрос.

Ответ 3

Нашел этот поток, пытаясь найти основную причину этой проблемы, потому что недавно у меня была аналогичная проблема, хотя моя память увеличивалась примерно на 1 Мб в минуту... Я в значительной степени выделил ее для разбора json. Запустите команду ajax с типом: "текст", и вы увидите, что память очищается.

Я нашел библиотеку json_parse.js, которая рекурсивно анализирует данные json с помощью JS-движка (не eval). Я вручную разбираю текстовые данные в json в обратном вызове успеха, и это хорошо работает.