Утечка памяти при вытягивании 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 в обратном вызове успеха, и это хорошо работает.