Sobes.tech
Middle

Ką žinote apie šiukšlių surinkėją Go kalboje?

sobes.tech AI

Atsakymas iš AI

Golang naudoja paralelinį ir žemą vėlavimą turintį šiukšlių surinkėją, pagrįstą mark-sweep algoritmu.

Pagrindinės savybės:

  1. Trys spalvos algoritmas (Three-color algorithm): Žymi objektus trimis spalvomis: baltą (potencialus šiukšlės), pilką (objektas pasiekiamas, bet jo palikuonys nėra tikrinami) ir juodą (objektas ir jo palikuonys pasiekiami).
  2. Paralelinis (Parallel): Veikia kartu su naudotojo gorutinėmis keliuose branduoliuose, minimalizuoja sustojimo laiką.
  3. Konkurentinis (Concurrent): Didžioji dalis GC darbo atliekama kartu su programos vykdymu.
  4. Žemo vėlavimo sustojimo laikas (Low-latency Stop-The-World): Visi gorutinų sustojimo laikas yra labai trumpas, naudojamas tik fazėse "pradžia žymėjimo" (start of marking) ir "žymėjimo pabaiga" (end of marking), siekiant užtikrinti objektų grafiko nuoseklumą.
  5. Pakartotinai naudojami nuskaitymai (Stack scanning): Nuskaitymas taip pat vyksta paraleliai ir konkurentiškai su STW.
  6. Hipo augimo tikslas (Heap growth target): GC siekia palaikyti tam tikrą užpildymo procentą po kiekvieno ciklo, siekiant išvengti per dažnų arba per retų ciklų. Šį slenkstį galima kontroliuoti per kintamąjį GOGC. Pagal numatytuosius nustatymus GOGC=100, tai reiškia, kad GC paleidžiamas, kai hipo dydis padvigubėja.

GC darbo ciklas susideda iš šių fazių:

  1. GCstart: Trumpa STW fazė. Nustato šakniniai objektai žymėjimui.
  2. GCmark: Konkurentinė fazė. GC eina per objektų grafą ir žymi pasiekiamus objektus (pilka -> juoda). Naudoja write barrier stebėti pakeitimus žymėjimo metu.
  3. GCmarktermination: Trumpa STW fazė. Baigia žymėjimą ir pereina prie sweep.
  4. GCsweep: Konkurentinė fazė. Pasiekiami (balti) objektai yra laisvinami. Ši fazė gali būti vykdoma foniniame režime arba pagal poreikį naujai atlaisvinus atmintį.

GC Go yra valdomas automatiškai ir dažniausiai nereikalauja rankinio kvietimo. GC našumą galima stebėti naudojant aplinkos kintamuosius GODEBUG=gctrace=1.

Pavyzdys stebėjimui:

$ GODEBUG=gctrace=1 go run your_program.go

gctrace išvestis rodo informaciją apie kiekvieną GC ciklą, įskaitant fazių laikus, hipo dydį ir STW laiką.

Optimizacijai GC, be GOGC nustatymų, galima apsvarstyti:

  • Sumažinti alokacijų skaičių (pavyzdžiui, pakartotinai naudojant buferius, vengiant nereikalingų konversijų).
  • Profilis naudojant "escape analysis" norint suprasti, kurie objektai yra alokuojami hipe.
  • Naudoti sync.Pool du kartus kuriamiems ir atlaisvinamiems objektams.