Middle+
Papaskinkite apie šiukšlių surinkėjo (Garbage Collector) darbo metodus.
sobes.tech AI
Atsakymas iš AI
Atliekų surinkėjas yra automatizuotas atminties valdymo procesas, kuris atlaisvina atmintį, užimamą objektais, kurie daugiau nėra naudojami programos.
Pagrindiniai darbo metodai:
-
Nuorodų skaitiklis (Reference Counting):
- Kiekvienas objektas turi skaitiklį, kuris saugo nuorodų skaičių į jį.
- Kai sukuriama nuoroda į objektą, skaitiklis didėja.
- Kai nuoroda išnyksta (pvz., kintamasis išeina iš apimties), skaitiklis mažėja.
- Kai skaitiklis pasiekia nulį, objektas laikomas neprieinamu ir jo atmintis atlaisvinama.
- Problemos: Negali apdoroti ciklinių nuorodų, kai du ar daugiau objektų nurodo vienas kitą, bet yra neprieinami iš išorės.
-
Traukiamasis atliekų surinkėjas (Tracing Garbage Collector):
- Dirba dviejų etapų: žymėjimo (marking) ir surinkimo (sweeping) arba suspaudimo (compacting).
- Žymėjimo etapas: prasideda nuo "šaknų" (root set) - objektų, kurie garantuotai prieinami (pvz., globalios kintamosios, steko objektai). GC pereina per visus pasiekiamus iš šaknų objektus ir juos pažymi kaip "gyvus".
- Surinkimo etapas: GC peržiūri visą krūvą. Nežymėti objektai laikomi "šiukšle" ir jų atmintis atlaisvinama.
- Suspaudimo etapas (pasirinktinai): po surinkimo GC gali perkelti "gyvus" objektus, kad pašalintų atminties fragmentaciją.
- Privalumai: gali apdoroti ciklines nuorodas.
- Trūkumai: gali sukelti programos sustojimus (stop-the-world), kol GC veikia.
Dažniausiai naudojami algoritmai:
- Mark-and-Sweep: pažymi gyvus objektus, tada surenka šiukšles.
- Mark-and-Compact: pažymi gyvus objektus, tada juos perkelia defragmentacijai.
- Copying: padalija krūvą į dvi dalis. Surinkimo metu GC kopijuoja gyvus objektus iš vienos dalies į kitą, tada laisvąją dalį atlaisvina.
- Generational: pagrįstas hipoteze, kad dauguma objektų miršta jauni. Krūva padalijama į kartas (pvz., jauna ir sena). GC dažniau surenka šiukšles jaunoje kartoje, kas sumažina pauzes.
Konkretus metodas priklauso nuo naudojamos programavimo kalbos ir jos įgyvendinimo. Pvz., Java ir C# naudoja skirtingus generacinius traukiančius surinkėjus. Python tradiciškai naudojo nuorodų skaitiklį su papildomu ciklinių nuorodų aptikimo mechanizmu, o naujesnėse versijose taip pat taikomi traukiančio surinkėjo elementai.