Middle+
Hol van a változó, amikor kiemelik egy goroutine-ban?
sobes.tech MI
Válasz az MI-től
Egy változó akár a gorutina veremén, akár a heapen is elhelyezhető. Ez a Go fordító escape analysis (kiszabadulási elemzés) mechanizmusával dől el.
Az escape analysis alapelvei:
- Ha a fordító bizonyítani tudja, hogy a változó csak egy függvényhívásban vagy csak egy gorutina veremén belül él (azaz, nem hivatkozik rá kívülről), akkor a változó a gorutina veremén kerül elhelyezésre. Ez gyorsabb, mivel a verem automatikusan kezelhető és nem igényel szemétgyűjtést.
- Ha a fordító nem tudja bizonyítani, hogy a változó csak a veremben van, vagy ha kívülről hivatkozások vannak rá (pl. pointerrel átadva másik függvénynek, globális változóba írva, pointerrel visszaadva egy függvényből), akkor a változó a heapen kerül elhelyezésre. A heap szemétgyűjtést igényel, ami lassíthatja a végrehajtást.
Példa veremre történő elhelyezésre:
// Az 'x' változó a gorutina veremén kerül elhelyezésre, mivel csak a függvényen belül használják.
func exampleStack() int {
x := 10
return x
}
Példa heapen történő elhelyezésre:
// Az 'p' (pointer to int) és az általa mutatott int a heapen lehet elhelyezve.
// Ez azért történik, mert a pointert a függvény visszaadja, és kívülről is használható.
func exampleHeap() *int {
x := 20 // Az érték 20 a heapen lehet
return &x // Visszaadjuk az x változó címét
}
Az escape analysis a fordítás során történik. Ellenőrizhető a -gcflags "-m" zászlóval:
// Fordítás a szemétgyűjtés elemzésével
go build -gcflags "-m" your_package_name
A fordító kimenete megmutatja, mely változók "escape to heap".
Tehát a változó helye (verem vs heap) nem azon múlik, hogy a változó gorutina részeként van-e elhelyezve, hanem azon, hogy a Go fordító hogyan elemzi az életciklusát és a hatókörét.