Sobes.tech
Middle+

Pastāstiet par atkritumu savācēja (Garbage Collector) darba metodēm.

sobes.tech AI

Atbilde no AI

Atkritumu savartynas ir ir pašalina atmintį, kurią užima objektai, kurie daugiau nėra naudojami programos.

Pagrindiniai darbo metodai:

  1. 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.
  2. 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.