node.js - Hanterar Typescript/Javascript:s skräpsamlare cirkulära referenser eller läcker den minne?
I språk som C# är detta inget problem, men detta skapar svårfunna minnesfel i några andra språk. Kan jag använda följande kod i Typescript eller Javascript och lita på att allt kommer att vara bra?
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
Eller borde jag göra variablerna kids och siblings valfria och lägga till en destructor? Något i stil med detta:
kids?: Kid[];
siblings?: Kid[];
destructor() {
this.kids = undefined
}
Här är ett relaterat ämne och jag var inte nöjd med svaret: Förstöra en cirkulär referens-instans i TypeScript?
Svar #1
TypeScript har ingen körningstid.
Det finns många JavaScript-runtime, så det är omöjligt att säga att något särskilt gäller för alla av dem, men alla de stora runtime-miljöerna (de som levereras med populära webbläsare, node.js) kan enkelt hantera bortkopplade cirkulära referenser.
Det finns en väldefinierad minnesrot i JS från vilken det är enkelt att göra en mark-and-sweep GC, som inte har några problem med att hantera cirkulära referenser. Cirkulära referenser är egentligen bara ett problem i ref-tällande GC-system och det finns ingen större anledning att göra ref-tä counting i JS-språket eftersom du inte behöver deterministisk rensning.