Middle
Jakie są Twoje znajomości zbieracza śmieci w języku Go?
sobes.tech AI
Odpowiedź od AI
Golang używa równoległego i niskolatencyjnego zbieracza śmieci opartego na algorytmie mark-sweep.
Główne cechy:
- Algorytm trójkolorowy (Three-color algorithm): Oznacza obiekty trzema kolorami: biały (potencjalny śmieć), szary (obiekt osiągalny, ale jego potomkowie nie są inspekcjonowani) i czarny (obiekt i jego potomkowie osiągalni).
- Paralelizm (Parallel): Działa równolegle z gorutynami użytkownika na wielu rdzeniach, minimalizując czas zatrzymania.
- Współbieżność (Concurrent): Większość pracy GC jest wykonywana jednocześnie z wykonywaniem programu.
- Minimalizacja czasu zatrzymania (Low-latency Stop-The-World): Czas zatrzymania wszystkich gorutyn (STW) jest niezwykle krótki, używany tylko do faz "początek oznaczania" (start of marking) i "zakończenie oznaczania" (end of marking), aby zapewnić spójność grafu obiektów.
- Ponowne użycie skanowania stosu (Stack scanning): Skanowanie stosów odbywa się również równolegle i współbieżnie z STW.
- Cel wzrostu sterty (Heap growth target): GC stara się utrzymać określony procent wypełnienia sterty po każdym cyklu, aby unikać zbyt częstych lub zbyt rzadkich cykli. Ten próg można kontrolować za pomocą zmiennej
GOGC. DomyślnieGOGC=100, co oznacza, że GC uruchamia się, gdy rozmiar sterty podwaja się.
Cykl pracy GC składa się z następujących faz:
- GCstart: Krótka faza STW. Określane są obiekty korzeniowe do oznaczania.
- GCmark: Faza współbieżna. GC przechodzi przez graf obiektów, oznaczając osiągalne obiekty (kolor szary -> czarny). Używa bariery zapisu do śledzenia zmian w grafie podczas oznaczania.
- GCmarktermination: Krótka faza STW. Kończy oznaczanie i przełącza z bariery zapisu na sweep.
- GCsweep: Faza współbieżna. Nieosiągalne (białe) obiekty są zwalniane. Ta faza może odbywać się w tle lub w razie potrzeby podczas alokacji nowej pamięci.
GC w Go jest zarządzany automatycznie i nie wymaga ręcznych wywołań w większości przypadków. Wydajność GC można monitorować za pomocą zmiennych środowiskowych GODEBUG=gctrace=1.
Przykład monitorowania:
$ GODEBUG=gctrace=1 go run your_program.go
Wyjście gctrace pokazuje informacje o każdym cyklu GC, w tym czasy faz, rozmiar sterty i czas STW.
Aby zoptymalizować GC, oprócz ustawienia GOGC, można rozważyć:
- Zmniejszenie liczby alokacji (np. ponowne użycie buforów, unikanie niepotrzebnych konwersji).
- Profilowanie pod kątem "escape analysis" w celu zrozumienia, które obiekty są alokowane na stercie.
- Użycie pul (
sync.Pool) dla często tworzonych i zwalnianych obiektów.