Sobes.tech
Middle+

Kus asub muutuja, kui see on esile tõstetud gorutinas?

sobes.tech AI

Vastus AI-lt

Muutuja võib eraldada nii virna, kui ka kogusse. See määratakse Go kompilaatori escape analysis (põgenemisanalüüsi) mehhanismi abil.

Põhilised põgenemisanalüüsi põhimõtted:

  • Kui kompilaator suudab tõestada, et muutuja elab ainult ühe funktsiooni väljakutse sees või ainult ühe gorutina virnas (st, sellele ei viidata väljastpoolt), siis eraldatakse see selle gorutina virna. See on kiirem, kuna virn hallatakse automaatselt ega vaja prügikoristust.
  • Kui kompilaator ei suuda tõestada, et muutuja on piiratud virnaga või sellele on viiteid väljastpoolt (näiteks edastatakse viitega teise funktsiooni, kirjutatakse globaalsesse muutuja või tagastatakse funktsioonist viitega), siis eraldatakse see kogusse. Kogus nõuab prügikoristust, mis võib aeglustada täitmist.

Näide virna eraldamisest:

// Muutuja 'x' eraldatakse gorutina virna, kuna seda kasutatakse ainult funktsiooni sees.
func exampleStack() int {
	x := 10
	return x
}

Näide kogusse eraldamisest:

// Muutuja 'p' (viide intile) ja sellele viitav väärtus võivad olla eraldatud kogusse.
// See toimub seetõttu, et viide tagastatakse funktsioonist ja seda saab kasutada väljastpoolt.
func exampleHeap() *int {
	x := 20 // Väärtus 20 võib olla eraldatud kogusse
	return &x // Tagastame muutuja x aadressi
}

Põgenemisanalüüs toimub kompileerimise ajal. Seda saab kontrollida, kasutades lipu -gcflags "-m":

go build -gcflags "-m" your_package_name

Kompilaatori väljund näitab, millised muutujad "escape to heap".

Seega, muutuja asukoht (virn vs kogus) määratakse mitte selle järgi, kas muutuja eraldatakse gorutinas, vaid selle järgi, kuidas Go kompilaator analüüsib selle elutsüklit ja ulatust.