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.