Sobes.tech
Middle+

Jak funguje sběrač odpadu v jazyce Go?

sobes.tech AI

Odpověď od AI

Garbage collector v jazyce Go implementuje paralelní, nepřesnou (non-generational) metodu založenou na algoritmu Mark-and-Sweep s triggerem podle objemu haldy.

Hlavní principy fungování:

  1. Trigger aktivace: Sběrač se spustí, když objem paměti přidělené programem překročí určitý práh, který je dynamicky regulován.
  2. Fáze označování (Mark Phase):
    • Sběrač pozastaví pouze kritickou část fáze označování (Stop-the-World, STW), ale to trvá velmi krátkou dobu.
    • Paralelně s běžícím programem (mutator) prochází graf objektů od kořenových ukazatelů (registry, globální proměnné, zásobníky gorutin).
    • Přístupné (živé) objekty jsou označeny jako používané.
  3. Fáze úklidu (Sweep Phase):
    • Po dokončení fáze označování prochází seznam paměťových spanů.
    • Neoznačené objekty jsou považovány za odpad a jejich paměť je uvolněna.
    • Tato fáze je také prováděna paralelně s během programu.
  4. Write Barrier: Go používá write barrier k sledování změn v grafu objektů během paralelní fáze označování. To zajišťuje správnou funkci sběrače i přes modifikace paměti mutátorem.
  5. Žádné generace: Na rozdíl od některých jiných jazyků, Go ne dělí objekty na generace. Sběrač zpracovává celou haldu jako celek.
  6. Cíl nízké latence: Při návrhu GC v Go bylo cílem minimalizovat zpoždění způsobená sběrem odpadků (pauzy STW), což ho činí vhodným pro serverové aplikace.

Paralelizace a použití write barrier umožňují sběrači minimalizovat dobu zastavení programu a zajistit vysoký výkon.

Příklad zjednodušené správy paměti (ne přímo GC, ale ilustruje uvolnění zdrojů):

package main

import (
	"fmt"
	"os"
)

func main() {
	// Příklad vytvoření dočasného zdroje, který bude uvolněn
	file, err := os.Create("temp.txt")
	if err != nil {
		fmt.Println("Chyba při vytváření souboru:", err)
		return
	}
	// Odložené uzavření souboru.
	// Ačkoliv to není GC v přímém smyslu, ukazuje uvolnění zdrojů.
	defer file.Close()

	fmt.Println("Soubor 'temp.txt' vytvořen.")

	// Poté může program pracovat se souborem...

	// GC pracuje automaticky na pozadí a sbírá nepoužívané objekty na haldě.
	// Například, pokud vytvoříme slice nebo mapu:
	data := make([]int, 1000000) // Alokace na haldě
	_ = data // Použití

	// Když data přestanou být dosažitelná (například při opuštění funkce),
	// garbage collector časem uvolní přidělenou paměť.
}