node.js - Behandelt der Typescript/Javascript Garbage Collector zirkuläre Referenzen oder führt er zu Speicherlecks?
In Sprachen wie C# ist dies kein Problem, aber in einigen anderen Sprachen führt dies zu schwer auffindbaren Speicherfehlern. Kann ich den folgenden Code in Typescript oder Javascript verwenden und darauf vertrauen, dass alles in Ordnung sein wird?
class Dad {
kids: Kid[];
}
class Kid {
dad: Dad;
siblings: Kid[];
}
let anakin: Dad | undefined;
function makeKids(dad: Dad) {
const luke = new Kid();
const leia = new Kid();
luke.dad = dad;
leia.dad = dad;
luke.siblings = [leia];
leia.siblings = [luke];
dad.kids = [luke, leia];
}
anakin = new Dad();
makeKids(anakin);
console.log(anakin.kids.length); // Prints out 2
anakin = undefined;
// I expect luke and leia to die at this point
// Not float around the memory space infinitely
Oder sollte ich die Variablen kids und siblings optional machen und einen destructor hinzufügen? So etwas wie dies:
kids?: Kid[];
siblings?: Kid[];
destructor() {
this.kids = undefined
}
Hier ist ein verwandtes Thema und ich war mit der Antwort nicht zufrieden: Eine zirkuläre Referenz-Instanz in TypeScript zerstören?
Antwort #1
TypeScript hat zur Laufzeit keine Umgebung.
Es gibt viele JavaScript-Laufzeiten, daher ist es unmöglich zu sagen, dass eine bestimmte Sache für alle von ihnen zutrifft, aber alle wichtigen Laufzeiten (die in beliebten Browsern, Node.js, ausgeliefert werden) sind problemlos in der Lage, mit getrennten zirkulären Referenzen umzugehen.
Es gibt eine klar definierte Speicherwurzel in JS, von der aus es einfach ist, eine Mark-and-Sweep-Garbage-Collection durchzuführen, die keine Probleme mit zirkulären Referenzen hat. Zirkuläre Referenzen sind wirklich nur ein Problem in referenzzählenden Garbage-Collection-Systemen, und es gibt keinen guten Grund, in der JS-Sprache Referenzzählung zu verwenden, da man keine deterministische Aufräumung benötigt.