Wie zerstöre ich ein JavaScript-Objekt?

79

Kürzlich bin ich auf eine meiner Anwendungen gestoßen, die zu viel Speicher verbraucht und um 10 MB / s zunimmt.

Daher möchte ich wissen, wie JavaScript-Objekte und -Variablen am besten zerstört werden können, damit der Speicherverbrauch niedrig bleibt und mein FF nicht zerstört werden kann.

Ich rufe alle 8 Sekunden zwei meiner JavaScript-Dateien auf, ohne die Seite neu zu laden.

function refresh() {
    $('#table_info').remove();
    $('#table').hide();
    if (refreshTimer) {
        clearTimeout(refreshTimer);
        refreshTimer = null ;
    }
    document.getElementById('refresh_topology').disabled=true; 
    $('<div id="preload_xml"></div>').html('<img src="pic/dataload.gif" alt="loading data" /><h3>Loading Data...</h3>').prependTo($("#td_123"));
    $("#topo").hide();
    $('#root').remove();
    show_topology();
}

Wie kann ich sehen, welche Variable den Speicheraufwand verursacht und welche Methode die Ausführung dieses Prozesses stoppt?

Amit Shah
quelle
1
Haben Sie darüber nachgedacht, Teile Ihrer Codes mithilfe von Verschlüssen zu isolieren?
YS.
1
Hast du etwas versucht? Wie mit obj = null?
Florian Margaine
A) Was macht show_topologydas? --- B) Räumen Sie jemals die Dinge auf, die Sie hinzufügen #td_123? --- C) Gibt es irgendwo eine Live-Version davon?
Deestan

Antworten:

92

Sie können Ihren gesamten Code wie folgt unter einen Namespace stellen:

var namespace = {};

namespace.someClassObj = {};

delete namespace.someClassObj;

Wenn Sie das deleteSchlüsselwort verwenden, wird der Verweis auf die Eigenschaft gelöscht. Auf niedriger Ebene erhält der JavaScript-Garbage Collector (GC) jedoch weitere Informationen darüber, welche Objekte zurückgefordert werden sollen.

Sie können auch Chrome Developer Tools verwenden, um ein Speicherprofil Ihrer App abzurufen und festzustellen, welche Objekte in Ihrer App verkleinert werden müssen.

Yochai Akoka
quelle
12
Drücken Sie F12, um Entwicklertools abzurufen. Gehen Sie zur Registerkarte Profil und klicken Sie auf Start, um das Profil zu starten. Sie können die Profilerstellung auf JS-CPU und CSS-Selektor durchführen und den Heap-Snapshot erstellen.
Sarath
3
oder in der neuesten Chromart das Wort Leistung in der js-Konsole
David Morrow
Vielleicht ist es offensichtlich, aber Sie können Ihren Namespace so etwas wie "g" benennen und viel Tipparbeit sparen. Verwenden Sie g.curItem = ... anstelle von var curItem = ... und speichern Sie die Eingabe sowie g = undefined, um die gesamte globale Speicherzuordnung zu löschen.
David Spector
31

Sie können Objekte nicht löschen. Sie werden entfernt, wenn keine Verweise mehr auf sie vorhanden sind. Sie können Referenzen mit löschen delete.

Wenn Sie jedoch Zirkelverweise in Ihren Objekten erstellt haben, müssen Sie möglicherweise einige Dinge entkoppeln.

CodeClown42
quelle
2
Können Sie ein Beispiel für einen Zirkelverweis hinzufügen, der vom Garbage Collector nicht erfasst wird? Nach einem Freund fragen! ;)
Emilhem
@emilhem Sie können auf den Garbage Collector verweisen und er löscht sich selbst und das Internet - die Implosion, die möglicherweise ein Schwarzes Loch am CERN erzeugt. Haben Sie über dieses Beispiel nachgedacht?
El Mac
28

Während die vorhandenen Antworten Lösungen zur Lösung des Problems und der zweiten Hälfte der Frage gegeben haben, geben sie keine Antwort auf den Selbstfindungsaspekt der ersten Hälfte der Frage, die fett gedruckt ist:

"Wie kann ich sehen, welche Variable Speicher-Overhead verursacht ...?"

Es war vor 3 Jahren vielleicht noch nicht so robust, aber der Abschnitt " Profile " der Chrome Developer Tools ist jetzt ziemlich leistungsfähig und funktionsreich. Das Chrome-Team hat einen aufschlussreichen Artikel über die Verwendung und damit auch über die Funktionsweise der Garbage Collection (GC) in Javascript, die den Kern dieser Frage bildet.

Da dies deleteim Grunde die Wurzel der derzeit von Yochai Akoka akzeptierten Antwort ist, ist es wichtig, sich daran zu erinnern, was das Löschen bewirkt. Es ist irrelevant, wenn es nicht mit den Konzepten kombiniert wird, wie GC in den nächsten beiden Antworten funktioniert: Wenn ein Verweis auf ein Objekt vorhanden ist, wird es nicht bereinigt. Die Antworten sind korrekter, aber wahrscheinlich nicht so geschätzt, weil sie mehr Gedanken erfordern als nur das Schreiben von "Löschen". Ja, eine mögliche Lösung könnte die Verwendung sein delete, aber es spielt keine Rolle, ob es einen anderen Verweis auf den Speicherverlust gibt.

In einer anderen Antwort werden Zirkelverweise angemessen erwähnt, und die Dokumentation des Chrome-Teams bietet viel mehr Klarheit sowie die Tools zur Überprüfung der Ursache.

Da deletehier erwähnt wurde, kann es auch nützlich sein, die Ressource Grundlegendes Löschen bereitzustellen . Obwohl es nicht in die eigentliche Lösung kommt, die wirklich mit dem Garbage Collector von Javascript zusammenhängt.

Shwaydogg
quelle
8

Strukturieren Sie Ihren Code so, dass sich alle Ihre temporären Objekte innerhalb von Closures anstelle von globalen Namespace- / globalen Objekteigenschaften befinden und den Bereich verlassen, wenn Sie damit fertig sind. GC wird sich um den Rest kümmern.

Oleg V. Volkov
quelle
1

Ich stand vor einem solchen Problem und hatte die Idee, einfach die innere HTML der Kinder des problematischen Objekts zu ändern.

adiv.innerHTML = "<div...> the original html that js uses </div>";

Scheint schmutzig, aber es hat mein Leben gerettet, wie es funktioniert!

Sergio Abreu
quelle