So geben Sie den Speicher in JavaScript frei

70

Ich arbeite mit Canvas und seinem ImageData-Objekt, das eine große Datenmenge enthält (Millionen von Ganzzahlen). Das Arbeiten mit einigen Arrays erfordert also bereits viel Speicher (bis zu 300 MB). Gibt es eine Möglichkeit, den Speicher eines Arrays freizugeben, wenn dies nicht erforderlich ist? Ich versuche, undefineddieser Variablen zuzuweisen . Ist es richtig?

Haynar
quelle
Sie können die Speicherzuordnung in Javascript nicht verwalten oder den Garbage Collector aufrufen.
Jared Farrish
1
Ich glaube, das ist alles was du tun kannst. Der Rest liegt beim Müllsammler.
Ken Wayne VanderLinde
Ich kann also nur so wenig Arrays wie möglich verwenden?
Haynar
4
Sie könnten nullanstelle vonundefined
Basile Starynkevitch
1
Es kann erwähnenswert sein, dass Sie, da Sie Grenzen an getImageData übergeben können, nicht unbedingt gleichzeitig am gesamten Bilddatenarray arbeiten müssen. Je nachdem, was Sie tun, wird möglicherweise weniger Arbeitsspeicher benötigt, um das Bild in Blöcken zu bearbeiten, sodass die Speicherbereinigung zwischen den Blöcken funktionieren kann.
James Clark

Antworten:

115

Wenn die Variable weiterhin besteht (z. B. global oder Teil einer dauerhaften Datenstruktur) und die Daten, auf die sie verweist, groß sind und Sie möchten, dass diese Daten für die Speicherbereinigung in Frage kommen, weisen Sie dieser Variablen zu Recht etwas Kleines zu. undefinedoder nulloder ""wird alles funktionieren. Sie löschen den Verweis auf die großen Datenmengen, damit diese für die Speicherbereinigung in Frage kommen. Wenn nichts anderes in Ihrem Javascript auf diese Daten verweist, kann es vom Garbage Collector freigegeben werden. Wenn irgendetwas anderes einen Verweis darauf hat, kann es nicht freigegeben werden.

Wenn Sie beispielsweise ein Array mit 10.000 Elementen in einer globalen Variablen gespeichert haben:

var largeDataArray = new Array(10000);

Und wenn Sie die meisten Elemente mit Daten gefüllt haben, können Sie zulassen, dass dieser Speicher für die Speicherbereinigung geeignet ist, indem Sie ihm einen anderen Wert zuweisen, z.

largeDataArray = null;

oder wenn Sie immer noch möchten, dass es sich um ein Array handelt:

largeDataArray = [];

Hinweis: Variablen, die selbst den Gültigkeitsbereich verlassen (wie lokale Variablen in Funktionen, die nicht Teil eines dauerhaften Abschlusses sind) oder Variablen in Objekten, die selbst den Gültigkeitsbereich verlassen, müssen nicht manuell gelöscht werden. Wenn sie den Gültigkeitsbereich verlassen oder wenn das übergeordnete Objekt gelöscht wird, können die darin enthaltenen Daten auch zur Speicherbereinigung verwendet werden.

Das Löschen einer Variablen muss also nur erfolgen, wenn Sie explizit Daten freigeben möchten, die in einer langlebigen Variablen gespeichert sind, und es ist normalerweise nur relevant, sich darüber Gedanken zu machen, wenn die Daten groß sind oder wenn Sie viele davon hinzufügen bis zu mehreren Megabyte Daten (die Speichernutzung ist auf Smartphones auf niedrigeren Ebenen von größerer Bedeutung als in Desktop-Browsern).

jfriend00
quelle
Vielen Dank für die gute Antwort :) Es wird ein Kandidat sein, als Lösung markiert zu werden, wenn keine neuen Fakten mehr hervorgehoben werden
Haynar
2
Es gibt ein deleteJavascript, aber es dient hauptsächlich zum Löschen von Eigenschaften aus Objekten, nicht wie das Löschen in C ++. Sie können alle über Lösch lesen hier .
jfriend00
1
@ Haynar Es ist ein Operator, keine Methode: developer.mozilla.org/en/JavaScript/Reference/Operators/delete
Matt Ball
1
largeDataArray.length = 0 löscht alle Elemente. largeDataArray = [] ändert die Referenz von largeDataArray löscht das ursprüngliche Array nicht und führt so etwas wie arrayA = [0, 1, 2] aus; arrayB = arrayA; arrayA = []; console.log (arrayA, arrayB) => [], [0,1,2]
Adam Michalski
2
@AdamMichalski - Der Punkt hier ist, dass durch die Neuzuweisung von Elementen largeDataArraydas vorherige Array für die Speicherbereinigung in Frage kommt (sofern keine anderen Verweise darauf vorhanden sind). Ja, Sie können .lengthje nach Ihren Umständen auch Null setzen .
jfriend00
3

JavaScript verfügt über eine automatische Speicherverwaltung. Speicher, der Objekte enthält, auf die nicht mehr verwiesen wird, kann nur dann gespeichert werden, wenn ein Speicherverlust vorliegt. Es ist im Allgemeinen nicht erforderlich undefined, Variablen manuell zuzuweisen .

Wenn Ihr Programm zu viel Speicher verwendet, sollten Sie die Arrays verkleinern , um nicht mehr benötigte Elemente zu entfernen. Siehe Array.pop, Array.shiftund Array.splice.

Matt Ball
quelle
42
Dies ist falsch, da es im Allgemeinen nicht erforderlich ist, Variablen manuell undefiniert zuzuweisen. Wenn Sie möchten, dass der von einer großen Variablen verbrauchte Speicher freigegeben wird und diese Variable eine lange Lebensdauer hat (z. B. global oder ein Teil eines Objekts, das weiterhin besteht), können Sie den Speicher freigeben, indem Sie der Variablen etwas sehr Kleines neu zuweisen Die großen Datenmengen, die verwendet wurden, haben also keine Verweise mehr darauf und können durch Müll gesammelt werden. Ich habe noch nicht abgelehnt, aber ich denke darüber nach, weil dieser Beitrag in einigen Fällen irreführend und in anderen falsch ist.
jfriend00
Es wird auch nicht empfohlen, sich zu sehr auf den Müllsammler zu verlassen. Bei Speichermangel versuchen die Garbage Collectors aggressiv, Speicher freizugeben. Obwohl die Garbage Collectors einen langen Weg zurückgelegt haben, kann eine solch aggressive Garbage Collection Ihre Leistung beeinträchtigen.
Surender Thakran