从 WEB 中拉取 JSON 时的内存泄漏 [英] Memory Leak When Pulling JSON from WEB

查看:27
本文介绍了从 WEB 中拉取 JSON 时的内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我花了几天时间研究这个问题,并从我能想到的各个角度进行了尝试.我正在开发一个简单的 Windows 7 小工具.此脚本将从远程 Web 服务器拉取 JSON 数据并将其放在页面上.我将 jQuery 1.6.2 用于 $.getJSON.脚本每次循环消耗更多内存.

var count = 1;$(document).ready(function () {更新视图();});函数更新视图(){$("#junk").html(count);计数++;$.getJSON( URL + "&callback=?", populateView);设置超时(更新视图,1000);}函数 populateView(status) {$("#debug").html(status.queue.mbleft + " MB Remaining
" + status.queue.mb + " MB Total");}

任何帮助将不胜感激....谢谢!

添加 JSON 数据示例

?({"queue":{"active_lang":"en","paused":true,"session":"39ad74939e89e6408f98998adfbae1e2","re​​start_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","re​​fresh_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","kbperssec":"0.00","speedlimit":"","webdir":"","queue_details":"0","diskspace2":"668.52"}})

EDIT 2: 将代码精简到这一点,但它仍然会泄漏.我认为这消除了作为贡献者遍历 DOM 的情况.

$(document).ready(function () {设置间隔(更新视图,1000);});函数更新视图(){$.getJSON( URL + "&callback=?", populateView);}函数 populateView(status) {}

编辑 3: 这不是 jQuery.我删除了 jQuery 并使用直接的 js 来完成它.仍然泄漏.

function init(){设置间隔(更新视图,1000);}函数更新视图(){var xhr = new XMLHttpRequest();xhr.open("GET", URL, false);xhr.setRequestHeader( "If-Modified-Since", "0");xhr.send('');}

所以...如果它不是 jQuery,那么不仅仅是在 IE 中(Chrome 也是如此).有没有搞错?!想法?

谢谢!

解决方案

我感觉 updateView 中的 setTimeout 函数导致了这种行为.要对此进行测试,您可以将代码修改为:

$(document).ready(function () {设置间隔(更新视图,1000);});函数更新视图(){$("#junk").html(count);计数++;$.getJSON( URL + "&callback=?", populateView);}函数 populateView(status) {$("#debug").html(status.queue.mbleft + " MB Remaining
" + status.queue.mb + " MB Total");}

setInterval 函数将每 x 毫秒一遍又一遍地执行传入的函数.这里到文档.

编辑 2:另一个性能问题(尽管它可能不是问题的关键)是您每秒都在遍历 DOM 以查找 $('#debug') 元素.您可以存储它并将其传递为:

 $(document).ready(function () {var debug = $('#debug');varjunk = $('#junk');setInterval(函数(){updateView(调试,垃圾)},1000);});功能更新视图(调试,垃圾){垃圾.html(计数);计数++;$.getJSON( URL + "&callback=?", function(status){populateView(status,debug)});}函数 populateView(status) {debug.html(status.queue.mbleft + " MB Remaining
" + status.queue.mb + " MB Total");}

编辑 3:我更改了上面的代码,因为我忘记接收来自服务器的响应.假设 queue 是返回的 JSON 的一个属性,那么代码应该如上.

编辑 4:这是一个非常有趣的问题.那么另一种方法.让我们假设仍然有一些客户端脚本阻塞了内存.这可能是什么?据我所知,剩下的只有两件事是 setInterval 和 $.getJSON 函数.$.getJSON 函数是一个简单的 ajax 请求包装器,它触发一个请求并等待来自服务器的响应.setInterval 函数有点特殊,因为它会设置定时器、触发函数等.

我认为,如果您设法在您的服务器上模仿这一点,或者甚至每隔 5 秒在您的浏览器中刷新此网页,您将能够看到处理您的请求的是客户端还是服务器.

I've spent days on this and hit it from every angle I can think of. I'm working on a simple windows 7 gadget. This script will pull JSON data from a remote web server and put it on the page. I'm using jQuery 1.6.2 for the $.getJSON. Script consumes more memory each loop.

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");
}

Any help would be greatly appreciated....Thank you!

EDIT: Add JSON data sample

?({"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"}})

EDIT 2: Stripped code down to this and it still leaks. I think that eliminates traversing the DOM as a contributor.

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

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

function populateView(status) {
}

EDIT 3: It's not jQuery. I removed jQuery and did it with straight js. Still leaks.

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

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

So...if it's not jQuery, not just in IE (Chrome too). What the heck?! Ideas?

Thank you!

解决方案

I have the feeling that the setTimeout function within the updateView is causing this behaviour. To test this you can modify your code to:

$(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: The setInterval function will execute the passed in function over and over every x miliseconds. Here to the docs.

EDIT 2: Another performance loose (Although it might not be critical to the issue) is that you are traversing the DOM every second to find the $('#debug') element. You could store that and pass it in as:

        $(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");
        }

Edit 3: I have changed the code above because I forgot to take in the response from the server. Assuming that queue is a property of the returned JSON then the code should be as above.

Edit 4: This is a very interesting issue. Another approach then. Lets assume then that there is still some client side scripts that are clogging the memory. What could this be? As far as is I understand the only two things left are the setInterval and the $.getJSON function. The $.getJSON function is a simple ajax request wrapper which fires a request and waits for the response from the server. The setInterval function is a bit more peculiar one because it will set up timers, fire functions, etc.

I think if you manage to mimic this on your server or even just refresh this webpage in your browser every second/5 secs you you will be able to see whether it is the client or the server that processes your request.

这篇关于从 WEB 中拉取 JSON 时的内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆