[ Web Proxy ]
URL:
Viewing: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/FinalizationRegistry [Back]  [Original]

FinalizationRegistry - JavaScript | MDN

Dieser Inhalt wurde automatisch aus dem Englischen bersetzt, und kann Fehler enthalten. Erfahre mehr ber dieses Experiment.

View in English Always switch to English

FinalizationRegistry

Baseline Weitgehend verfgbar *

Diese Funktion ist gut etabliert und funktioniert auf vielen Gerten und in vielen Browserversionen. Sie ist seit April 2021 browserbergreifend verfgbar.

* Einige Teile dieser Funktion werden mglicherweise unterschiedlich gut untersttzt.

Ein FinalizationRegistry-Objekt ermglicht es Ihnen, einen Rckruf anzufordern, wenn ein Wert vom Garbage Collector eingesammelt wird.

In diesem Artikel

Beschreibung

FinalizationRegistry bietet eine Mglichkeit, anzufordern, dass ein Bereinigungs-Rckruf zu einem bestimmten Zeitpunkt aufgerufen wird, wenn ein im Registry registrierter Wert zurckgewonnen (durch den Garbage Collector eingesammelt) wurde. (Bereinigungs-Rckrufe werden manchmal Finalisierer genannt.)

Hinweis: Bereinigungs-Rckrufe sollten nicht fr wesentliche Programmlogik verwendet werden. Siehe Anmerkungen zu Bereinigungs-Rckrufen fr Details.

Sie erstellen die Registry, indem Sie den Rckruf bergeben:

js
const registry = new FinalizationRegistry((heldValue) => {
  // 
});

Dann registrieren Sie jeden Wert, fr den Sie einen Bereinigungs-Rckruf wnschen, indem Sie die Methode register aufrufen und den Wert sowie einen gehaltenen Wert dafr bergeben:

js
registry.register(target, "some value");

Die Registry hlt keine starke Referenz auf den Wert, da dies den Zweck vereiteln wrde (wenn die Registry ihn stark hielte, wrde der Wert niemals zurckgewonnen werden). In JavaScript sind Objekte und nicht registrierte Symbole durch den Garbage Collector einsammelbar, daher knnen sie in einem FinalizationRegistry-Objekt als Ziel oder Token registriert werden.

Wenn target zurckgewonnen wird, kann Ihr Bereinigungs-Rckruf zu einem bestimmten Zeitpunkt mit dem gehaltenen Wert aufgerufen werden, den Sie dafr bereitgestellt haben (some value im obigen Beispiel). Der gehaltene Wert kann ein beliebiger Wert sein: ein primitiver Wert oder ein Objekt, sogar undefined. Wenn der gehaltene Wert ein Objekt ist, hlt die Registry eine starke Referenz darauf (damit sie ihn spter an Ihren Bereinigungs-Rckruf bergeben kann).

Falls Sie mglicherweise spter einen registrierten Zielwert abmelden mchten, bergeben Sie einen dritten Wert, das sogenannte Abmeldetoken, das Sie spter verwenden werden, wenn Sie die Funktion unregister der Registry aufrufen, um den Wert abzumelden. Die Registry hlt nur eine schwache Referenz auf das Abmeldetoken.

Es ist blich, den Zielwert selbst als Abmeldetoken zu verwenden, was vllig in Ordnung ist:

js
registry.register(target, "some value", target);
// 

// some time later, if you don't care about `target` anymore, unregister it
registry.unregister(target);

Es muss jedoch nicht derselbe Wert sein; es kann ein anderer sein:

js
registry.register(target, "some value", token);
// 

// some time later
registry.unregister(token);

Vermeiden, wo mglich

Die korrekte Verwendung von FinalizationRegistry erfordert sorgfltiges berlegen, und es ist am besten, sie zu vermeiden, wenn mglich. Es ist auch wichtig, sich nicht auf spezifische Verhaltensweisen zu verlassen, die von der Spezifikation nicht garantiert werden. Wann, wie und ob eine Speicherbereinigung erfolgt, hngt von der Implementierung einer bestimmten JavaScript-Engine ab. Ein Verhalten, das Sie in einer Engine beobachten, kann in einer anderen Engine, in einer anderen Version derselben Engine oder sogar in einer etwas anderen Situation mit derselben Version derselben Engine unterschiedlich sein. Die Speicherbereinigung ist ein schwieriges Problem, an dem Implementierer von JavaScript-Engines stndig arbeiten, um ihre Lsungen zu verfeinern und zu verbessern.

Hier sind einige spezielle Punkte, die von den Autoren im Vorschlag aufgenommen wurden, der FinalizationRegistry eingefhrt hat:

Garbage Collector sind kompliziert. Wenn eine Anwendung oder Bibliothek davon abhngig ist, dass die GC eine WeakRef rechtzeitig und vorhersehbar bereinigt oder einen Finalisierer [Bereinigungs-Rckruf] aufruft, wird sie wahrscheinlich enttuscht: Die Bereinigung kann viel spter geschehen als erwartet, oder berhaupt nicht. Quellen der Variabilitt umfassen:

  • Ein Objekt knnte viel frher eingesammelt werden als ein anderes, selbst wenn sie gleichzeitig unerreichbar werden, z.B. aufgrund von Generationensammlung.
  • Die Arbeit der Speicherbereinigung kann ber die Zeit hinweg mit inkrementellen und parallelen Techniken aufgeteilt werden.
  • Verschiedene Laufzeit-Heuristiken knnen verwendet werden, um den Speicherverbrauch und die Reaktionsfhigkeit auszugleichen.
  • Die JavaScript-Engine kann Referenzen auf Dinge halten, die so aussehen, als wren sie unerreichbar (z.B. in Closures oder Inline-Caches).
  • Verschiedene JavaScript-Engines knnen diese Dinge unterschiedlich handhaben, oder dieselbe Engine kann ihre Algorithmen ber Versionen hinweg ndern.
  • Komplexe Faktoren knnen dazu fhren, dass Objekte fr unerwartet lange Zeit erhalten bleiben, wie etwa die Verwendung mit bestimmten APIs.

Anmerkungen zu Bereinigungs-Rckrufen

  • Entwickler sollten sich nicht auf Bereinigungs-Rckrufe fr wesentliche Programmlogik verlassen. Bereinigungs-Rckrufe knnen ntzlich sein, um den Speicherverbrauch im Verlauf eines Programms zu reduzieren, sind aber ansonsten wahrscheinlich nicht ntzlich.
  • Wenn Ihr Code gerade erst einen Wert in die Registry registriert hat, wird dieses Ziel nicht zurckgewonnen, bevor das Ende des aktuellen JavaScript-Jobs erreicht ist. Siehe Anmerkungen zu WeakRefs fr Details.
  • Eine konforme JavaScript-Implementierung, selbst eine mit Speicherbereinigung, ist nicht verpflichtet, Bereinigungs-Rckrufe aufzurufen. Wann und ob dies geschieht, liegt vollstndig an der Implementierung der JavaScript-Engine. Wenn ein registriertes Objekt zurckgewonnen wird, knnen die Bereinigungs-Rckrufe dafr zu diesem Zeitpunkt, spter oder gar nicht aufgerufen werden.
  • Es ist wahrscheinlich, dass groe Implementierungen Bereinigungs-Rckrufe irgendwann whrend der Ausfhrung aufrufen, aber diese Aufrufe knnten erheblich nach dem Zeitpunkt erfolgen, zu dem das damit verbundene Objekt zurckgewonnen wurde. Auerdem, wenn ein Objekt in zwei Registries registriert ist, gibt es keine Garantie, dass die beiden Rckrufe nebeneinander aufgerufen werden - einer kann aufgerufen werden und der andere nie, oder der andere kann viel spter aufgerufen werden.
  • Es gibt auch Situationen, in denen selbst Implementierungen, die normalerweise Bereinigungs-Rckrufe aufrufen, dies wahrscheinlich nicht tun:
    • Wenn das JavaScript-Programm vollstndig herunterfhrt (zum Beispiel das Schlieen eines Tabs im Browser).
    • Wenn die FinalizationRegistry-Instanz selbst nicht mehr durch JavaScript-Code erreichbar ist.
  • Wenn das Ziel einer WeakRef auch in einer FinalizationRegistry ist, wird das Ziel der WeakRef gleichzeitig oder vor einem mit dem Registry assoziierten Bereinigungs-Rckruf gelscht; wenn Ihr Bereinigungs-Rckruf deref auf einer WeakRef fr das Objekt aufruft, erhlt er undefined.

Konstruktor

FinalizationRegistry()

Erstellt ein neues FinalizationRegistry-Objekt.

Instanzeigenschaften

Diese Eigenschaften sind auf FinalizationRegistry.prototype definiert und werden von allen FinalizationRegistry-Instanzen gemeinsam genutzt.

FinalizationRegistry.prototype.constructor

Die Konstrukturfunktion, die das Instanzobjekt erstellt hat. Bei FinalizationRegistry-Instanzen ist der Ausgangswert der FinalizationRegistry-Konstruktor.

FinalizationRegistry.prototype[Symbol.toStringTag]

Der Anfangswert der [Symbol.toStringTag]-Eigenschaft ist der String "FinalizationRegistry". Diese Eigenschaft wird in Object.prototype.toString() verwendet.

Instanzmethoden

FinalizationRegistry.prototype.register()

Registriert ein Objekt bei der Registry, um einen Bereinigungs-Rckruf zu erhalten, wenn das Objekt durch den Garbage Collector eingesammelt wird.

FinalizationRegistry.prototype.unregister()

Meldet ein Objekt von der Registry ab.

Beispiele

Erstellen einer neuen Registry

Sie erstellen die Registry, indem Sie den Rckruf bergeben:

js
const registry = new FinalizationRegistry((heldValue) => {
  // 
});

Objekte fr die Bereinigung registrieren

Dann registrieren Sie alle Objekte, fr die Sie einen Bereinigungs-Rckruf wnschen, indem Sie die Methode register aufrufen und das Objekt sowie einen gehaltenen Wert dafr bergeben:

js
registry.register(theObject, "some value");

Rckrufe werden niemals synchron aufgerufen

Unabhngig davon, wie viel Druck Sie auf den Garbage Collector ausben, wird der Bereinigungs-Rckruf niemals synchron aufgerufen. Das Objekt kann synchron zurckgewonnen werden, aber der Rckruf wird immer irgendwann nach Abschluss des aktuellen Jobs aufgerufen:

js
let counter = 0;
const registry = new FinalizationRegistry(() => {
  console.log(`Array gets garbage collected at ${counter}`);
});

registry.register(["foo"]);

(function allocateMemory() {
  // Allocate 50000 functions  a lot of memory!
  Array.from({ length: 50000 }, () => () => {});
  if (counter > 5000) return;
  counter++;
  allocateMemory();
})();

console.log("Main job ends");
// Logs:
// Main job ends
// Array gets garbage collected at 5001

Wenn Sie jedoch zwischen jeder Zuteilung eine kleine Pause zulassen, kann der Rckruf eventuell frher aufgerufen werden:

js
let arrayCollected = false;
let counter = 0;
const registry = new FinalizationRegistry(() => {
  console.log(`Array gets garbage collected at ${counter}`);
  arrayCollected = true;
});

registry.register(["foo"]);

(function allocateMemory() {
  // Allocate 50000 functions  a lot of memory!
  Array.from({ length: 50000 }, () => () => {});
  if (counter > 5000 || arrayCollected) return;
  counter++;
  // Use setTimeout to make each allocateMemory a different job
  setTimeout(allocateMemory);
})();

console.log("Main job ends");

Es gibt keine Garantie dafr, dass der Rckruf frher aufgerufen wird oder berhaupt aufgerufen wird, aber es besteht die Mglichkeit, dass die geloggte Nachricht einen Zhlerwert hat, der kleiner als 5000 ist.

Spezifikationen

Spezifikation
ECMAScript 2027 LanguageSpecification
# sec-finalization-registry-objects

Browser-Kompatibilitt

Siehe auch


Web Proxy Viewer  |  New URL  |  Original Page