2 Stimmen

Speicherleck beim Abrufen von JSON aus WEB

Ich habe tagelang darüber nachgedacht und die Sache von allen Seiten angegangen, die ich mir vorstellen kann. Ich arbeite an einem einfachen Windows 7 Gadget. Dieses Skript wird JSON-Daten von einem Remote-Webserver ziehen und es auf der Seite setzen. Ich verwende jQuery 1.6.2 für die $.getJSON. Das Skript verbraucht mit jeder Schleife mehr Speicher.

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

Für jede Hilfe wären wir Ihnen sehr dankbar....Danke!

EDITAR: JSON-Datenbeispiel hinzufügen

?({"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: Ich habe den Code auf diesen Wert reduziert und er ist immer noch undicht. Ich denke, dass das Traversieren des DOM als einen Beitrag beseitigt.

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

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

function populateView(status) {
}

EDIT 3: Es ist nicht jQuery. Ich entfernte jQuery und tat es mit gerade js. Immer noch Lecks.

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

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

Also... wenn es nicht jQuery ist, nicht nur im IE (auch Chrome). Was zur Hölle?! Ideen?

Ich danke Ihnen!

2voto

Russ Clarke Punkte 16993

Bearbeiten 2:

Wenn es tatsächlich der Taskmanager ist, der hier das Leck zeigt, dann denke ich, dass der nächste Schritt darin besteht, den IE zu untersuchen, da ich glaube, dass der IE dann zum Hosten von Windows-Widgets verwendet wird.

Wenn Sie Ihr Skript in einer kleinen Html-Datei nachbilden können, können Sie dieses Tool ausführen und nachsehen, ob es der IE ist, der das Problem verursacht:

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

Benutzen Sie IE8 oder 9?


Editer :

Basierend auf dem JSON-String in der Op; im Grunde ist das Problem hier irreführend. das Bit von Javascript gepostet funktioniert völlig problemlos.

Der Server, der das JSON erzeugt, ist derjenige, der einen Unterschied in der Speichernutzung anzeigt. Ich würde die Website/den Endpunkt untersuchen, die/der das JSON erzeugt, und sehen, was das Problem ist.


Ich hatte gerade einen Gedanken,

$.getJSON ist nur eine Abkürzungsfunktion für den $.ajax-Aufruf von jQuery.

Ich frage mich, ob es einen Unterschied macht, wenn Sie Ihren Code ändern, um $.ajax zu verwenden, aber speziell den Cache-Mechanismus hinzuzufügen:

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

Das könnte dazu führen, dass er nicht mehr versucht, sie im Speicher abzulegen, und je nach Browser zeigt er vielleicht mehr Speicher an, weil Sie sozusagen noch keinen Garbage Collect haben.

2voto

sTodorov Punkte 5307

Ich habe das Gefühl, dass die setTimeout-Funktion innerhalb der updateView dieses Verhalten verursacht. Um dies zu testen, können Sie Ihren Code ändern, um:

$(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: Die Funktion setInterval führt die übergebene Funktion immer wieder alle x Millisekunden aus. Ici zu den Dokumenten.

EDIT 2: Eine weitere Leistungseinbuße (auch wenn sie für das Problem möglicherweise nicht entscheidend ist) besteht darin, dass Sie das DOM jede Sekunde durchlaufen, um die $('#debug') Element. Sie könnten das speichern und es als übergeben:

        $(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: Ich habe den obigen Code geändert, weil ich vergessen habe, die Antwort des Servers zu berücksichtigen. Angenommen, dass queue eine Eigenschaft des zurückgegebenen JSON ist, sollte der Code wie oben aussehen.

Edit 4: Dies ist ein sehr interessantes Thema. Ein anderer Ansatz also. Nehmen wir an, dass es noch einige clientseitige Skripte gibt, die den Speicher verstopfen. Was könnte das sein? Soweit ich weiß, sind die einzigen zwei Dinge, die übrig sind, die setInterval und die $.getJSON Funktion. Die Funktion $.getJSON ist ein einfacher Ajax-Request-Wrapper, der eine Anfrage auslöst und auf die Antwort des Servers wartet. Die setInterval-Funktion ist ein bisschen eigenartiger, weil sie Zeitgeber, Funktionen usw. einrichtet.

Ich denke, wenn Sie es schaffen, dies auf Ihrem Server nachzuahmen oder auch nur diese Webseite in Ihrem Browser alle 5 Sekunden zu aktualisieren, werden Sie in der Lage sein zu sehen, ob es der Client oder der Server ist, der Ihre Anfrage bearbeitet.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X