Wird beim Zuweisen eines neuen Zeichenfolgenwerts ein Müll erstellt, der gesammelt werden muss?

8

Betrachten Sie diesen JavaScript-Code:

%Vor%

Wird der Garbage Collector (GC) nach dieser Art von Operation noch etwas zu tun haben?

(Ich frage mich, ob ich mir Sorgen darüber machen sollte, String-Literale zuzuweisen, wenn ich GC-Pausen minimieren möchte.)

e: Ich bin ein bisschen amüsiert, dass, obwohl ich in meiner Frage ausdrücklich darauf hinwies, dass ich GC minimieren musste, meinten alle, dass ich falsch liege. Wenn man wirklich die besonderen Details kennen muss: Ich habe ein Spiel in Javascript - es läuft gut in Chrome, aber in Firefox hat halb-häufige Pausen, die auf GC zurückzuführen zu sein scheinen. (Ich habe sogar mit der MemChaser-Erweiterung für Firefox überprüft, und die Pausen stimmen genau mit der Speicherbereinigung überein.)

    
starwed 29.11.2012, 00:45
quelle

5 Antworten

8

Ja, Zeichenfolgen müssen wie alle anderen dynamisch zugewiesenen Objekte mit einem Garbage-Collector gesammelt werden. Und ja, das ist ein berechtigtes Problem, da unvorsichtiges Zuordnen von Objekten innerhalb von ausgelasteten Schleifen definitiv Leistungsprobleme verursachen kann.

String-Werte sind jedoch unveränderlich (nicht änderbar), und die meisten modernen JavaScript-Implementierungen verwenden "String-Interning", dh sie speichern nur eine Instanz jedes eindeutigen String-Werts. Das heißt, wenn Sie so etwas haben ...

%Vor%

... nur eine Instanz von "abc" wird zugewiesen. Dies gilt nur für String-Werte, nicht für String -Objekte.

Ein paar Dinge zu beachten:

  1. Funktionen wie substring , slice usw. weisen für jeden Funktionsaufruf ein neues Objekt zu (falls mit anderen Parametern aufgerufen).

  2. Obwohl beide Variablen auf dieselben Daten im Speicher zeigen, müssen beim Ausführen des GC-Zyklus noch zwei Variablen verarbeitet werden. Wenn Sie zu viele lokale Variablen haben, können Sie sich ebenfalls verletzen, da jeder von ihnen vom GC verarbeitet werden muss, was zusätzlichen Aufwand verursacht.

Eine weitere Lektüre zum Schreiben von Hochleistungs-JavaScript:

alekop 29.11.2012, 01:39
quelle
0

Ja, aber wenn Sie dies nicht millionenfach in einer Schleife machen, wird es wahrscheinlich kein Problem für Sie sein, sich Sorgen zu machen.

    
Tad 29.11.2012 00:55
quelle
0

Wie Sie bereits bemerkt haben, ist JavaScript kein JavaScript. Es läuft auf verschiedenen Plattformen und hat daher unterschiedliche Leistungsmerkmale. Also die definitive Antwort auf die Frage "Wird der GC nach dieser Art von Operation zu arbeiten haben?" ist: vielleicht. Wenn das Skript so kurz ist, wie Sie es gezeigt haben, könnte ein JIT-Compiler die erste Zeichenfolge vollständig löschen. Aber in der Sprachdefinition gibt es keine Regel, die besagt, dass es so oder anders sein muss. Am Ende ist es so, als ob es allzu oft in JavaScript ist: Sie müssen es versuchen.

Die interessantere Frage könnte auch sein: Wie können Sie die Speicherbereinigung vermeiden? Und das ist der Versuch, die Zuweisung neuer Objekte zu minimieren. Spiele haben in der Regel eine ziemlich konstante Anzahl von Objekten und oft werden keine neuen Objekte vorhanden sein, bis ein altes nicht mehr benutzt wird. Für Strings könnte dies schwieriger sein, da sie in JS unveränderlich sind. Versuchen Sie also, Strings möglichst durch andere (veränderliche) Repräsentationen zu ersetzen.

    
Mene 29.11.2012 01:27
quelle
0

Ja, der Garbage Collector wird ein String-Objekt haben, das "Some string" enthält, um loszuwerden. Und als Antwort auf Ihre Frage wird diese String-Zuweisung für den GC funktionieren.

Da Strings unveränderlich sind und häufig verwendet werden, hat die JS-Engine eine ziemlich effiziente Möglichkeit, mit ihnen umzugehen. Sie sollten keine Pausen von Müll bemerken, die ein paar Strings sammeln. Der Müllsammler hat im normalen Ablauf der JavaScript-Programmierung ständig zu arbeiten. So soll es funktionieren.

Wenn Sie Pausen von GC beobachten, bezweifle ich eher, dass es aus ein paar Strings besteht. Es ist wahrscheinlicher ein viel größeres Problem. Entweder haben Sie Tausende von Objekten, die GC benötigen oder eine sehr komplizierte Aufgabe für den GC. Darüber können wir nicht wirklich spekulieren, ohne den Gesamtcode zu studieren.

Dies sollte kein Problem sein, es sei denn, Sie haben eine riesige Schleife gemacht und mit Zehntausenden von Objekten zu tun gehabt. In diesem Fall könnte man etwas genauer programmieren, um die Anzahl der erstellten Zwischenobjekte zu minimieren. Aber, ohne diese Ebene von Objekten, sollten Sie zuerst klaren, zuverlässigen Code und dann für die Leistung optimieren, nur wenn etwas Ihnen gezeigt hat, dass es ein Leistungsproblem gibt, um das Sie sich sorgen müssen.

    
jfriend00 29.11.2012 00:54
quelle
-2

Um Ihre Frage zu beantworten: "Ich frage mich, ob ich mir Sorgen darüber machen sollte, String-Literale zuzuweisen, wenn GC-Pausen minimiert werden sollen": Nein.

Sie müssen sich im Hinblick auf die Garbage-Collection wirklich keine Gedanken darüber machen.

GC ist nur ein Problem beim Erstellen von & amp; eine große Anzahl von Javascript-Objekten oder eine große Anzahl von DOM-Elementen zu zerstören.

    
Jed Watson 29.11.2012 00:56
quelle