Ich habe viel darüber recherchiert, aber hauptsächlich, indem ich andere Fragen zusammengefügt habe, was noch immer Zweifel aufkommen lässt. In einer App, die die Browserseite zu keinem Zeitpunkt aktualisiert und für einige Zeit (Stunden) ohne Schließen leben kann (vorausgesetzt, dass das Aktualisieren einer Seite oder das Navigieren zu einer anderen den JS-Code neu startet), ist der beste Weg zur Sicherstellung von Objekten freigegeben und es gibt keinen Speicherverlust.
Dies sind die spezifischen Szenarien, die mich interessieren:
Der gesamte folgende Code befindet sich in einem aufschlussreichen Modulmuster.
%Vor%Variablen innerhalb von Funktionen, ich bin mir sicher, dass diese vom GC einfach gesammelt werden
%Vor%Variablen innerhalb des Moduls, sollte g = null, wenn es nicht mehr benötigt wird?
%Vor%Und schließlich das Leben eines jqXHR: Wird es nach der Rückkehr aufgeräumt? Sollte es vorsichtshalber in einer Funktion oder in einem Modul auf Null gesetzt werden?
Wenn dies geschieht, wird es nach der Rückkehr vom GC bereinigt?:
%Vor%Wie wäre es damit, wird es auch bereinigt, nachdem x zurückkommt?:
%Vor%Schließlich gibt es eine Möglichkeit, alle Variablen zu bereinigen und ein Modul neu zu starten, ohne den Browser neu zu starten?
Variablen innerhalb von Funktionen, ich bin mir sicher, dass diese vom GC einfach gesammelt werden
Ja.
Variablen innerhalb des Moduls, sollte g = null, wenn es nicht mehr benötigt wird?
Sicher.
Und schließlich das Leben eines jqXHR: Wird es nach der Rückkehr aufgeräumt? Sollte es vorsichtshalber in einer Funktion oder in einem Modul auf Null gesetzt werden?
Verschiedene Browser hatten Fehler im Zusammenhang mit XHR, die dazu führten, dass onreadystatechange
und alles, was geschlossen wurde, nicht einholbar waren, es sei denn, der Entwickler war vorsichtig, es durch einen Dummy-Wert zu ersetzen ( xhr.onreadystatechange = new Function('')
), aber ich glaube, dass jQuery dies für Sie erledigt .
Schließlich gibt es eine Möglichkeit, alle Variablen zu bereinigen und ein Modul neu zu starten, ohne den Browser neu zu starten?
Der mit der Seite verknüpfte globale Status nimmt den Browserspeicher auf, bis die Seite aus dem Browserprotokollstapel entfernt wird. location.replace
kann Ihnen hier helfen, indem Sie die aktuelle Seite beenden und durch eine neue Version von die gleiche App, ohne den History-Stack zu erweitern.
Ersetzen Sie das aktuelle Dokument durch das unter der angegebenen URL. Der Unterschied zur Methode
assign()
besteht darin, dass nach der Verwendung vonreplace()
die aktuelle Seite nicht im Sitzungsverlauf gespeichert wird, dh der Benutzer kann die Schaltfläche Zurück nicht verwenden, um dorthin zu navigieren.
Wenn Sie das Wort "Modul" verwenden, ist das kein Begriff, der eine wohldefinierte Bedeutung für den Browser oder seinen JavaScript-Interpreter hat, so dass es keine Möglichkeit gibt, ein Modul und nur ein Modul aus dem Speicher zu entfernen. Es gibt mehrere Dinge, über die Sie sich Gedanken machen müssen, die Dinge im Gedächtnis behalten könnten:
setInterval
und setTimeout
Callbacks und alles, was sie schließen. Jedes Schema, das ein Modul entlädt und nur ein Modul, müsste sich mit all diesen befassen und herausfinden, welche von ihnen Teil des Moduls sind und welche nicht. Das sind viele verschiedene Arten von Aufräumarbeiten.
Javascript ist eine Müll-gesammelte Sprache. Es beruht auf dem Garbage Collector, um nicht verwendeten Speicher zu bereinigen. Im Wesentlichen müssen Sie darauf vertrauen, dass der GC seine Arbeit machen wird.
Der GC wird (eventuell nicht sofort) Objekte sammeln, die für Sie nicht erreichbar sind. Wenn Sie einen Verweis auf ein Objekt haben, wird es möglicherweise noch verwendet, und der GC wird es nicht berühren.
Wenn Sie weder direkt noch indirekt auf das Objekt verweisen, weiß der GC, dass das Objekt nicht verwendet werden kann und das Objekt erfasst werden kann. Alles, was Sie wirklich tun müssen, ist sicherzustellen, dass Sie alle Verweise auf das Objekt zurücksetzen.
Der GC gibt jedoch keine Garantie für , wenn das Objekt erfasst wird. Und darüber solltest du dir keine Sorgen machen.
Wirklich die einzigen Lecks, um die Sie sich sorgen sollten, sind Schließungen.
%Vor% Der GC hat keine Möglichkeit, var b
zu löschen - er liegt außerhalb des Bereichs. Dies ist ein großes Problem mit IE, nicht so sehr mit Mozilla und noch weniger mit Chrome.
Als Faustregel gilt, dass Sie bei jeder von Garbage Collection gesammelten Sprache (dies gilt z. B. für Java, .NET und JavaScript) sicherstellen möchten, dass kein verweilender Verweis auf einen gewünschten Speicherblock vorhanden ist den GC für dich aufräumen zu lassen. Wenn der GC einen Speicherblock betrachtet und feststellt, dass sich im Programm immer noch etwas befindet, wird darauf hingewiesen, dass es nicht freigegeben wird.
In Bezug auf den jqXHR ist es sinnlos, sie am Ende eines AJAX-Funktionsaufrufs auf null zu setzen. Alle Parameter eines AJAX success / error / complete werden freigegeben, sobald die Funktion vom GC zurückgegeben wird, es sei denn, jQuery macht etwas bizarres, wie einen Verweis auf sie zu behalten.
Jede Variable, auf die Sie nicht mehr zugreifen können, kann vom GC erfasst werden. Wenn Sie eine Variable innerhalb einer Funktion deklarieren, kann die Variable nach dem Beenden der Funktion entfernt werden. ist , wenn der Computer nicht mehr genügend Speicherplatz hat oder zu einem anderen Zeitpunkt.
Dies wird komplizierter, wenn Sie asynchrone Funktionen wie XHR ausführen. Die Schließungen done und fail können auf alle in den äußeren Funktionen deklarierten Variablen zugreifen. Solange also done und fail ausgeführt werden können, müssen alle Variablen im Speicher verbleiben. Sobald die Anfrage beendet ist, können die Variablen freigegeben werden.
Wie auch immer, Sie sollten einfach sicherstellen, dass jede Variable so tief wie möglich deklariert ist.
Ist das erste Beispiel mit 'g', sollte g auf Null gesetzt werden. Andernfalls wird der Zeiger auf "dd" beibehalten.
Im zweiten Beispiel muss das "x" im ersten Fall nicht auf null gesetzt werden, da diese Variable "verschwindet", wenn die umgebende Funktion beendet wird. Im zweiten Fall, mit 'x' außerhalb der Funktion, behält 'x', was auch immer ihm zugewiesen ist, und das wird nicht GC'd, bis 'x' auf null oder etwas anderes gesetzt ist.
Tags und Links javascript memory-leaks jquery