Middle+
Hoe zijn goroutines opgebouwd en hoeveel geheugen nemen ze in de stack in beslag?
sobes.tech AI
Antwoord van AI
Een goroutine is een lichtgewicht uitvoeringsdraad die wordt beheerd door de runtime-omgeving van Go. In tegenstelling tot OS-threads worden goroutines gemultiplexed op een kleiner aantal OS-threads. Dit zorgt voor betere schaalbaarheid.
Belangrijke aspecten:
- Scheduler: De Go-runtime heeft zijn eigen scheduler (M:N scheduler), die goroutines (M) beheert op een beperkt aantal OS-threads (N).
- Memory Manager: Beheert de stacks van goroutines en hun groei/krimp.
- Communicatie: Goroutines communiceren via kanalen, wat veilige gegevensuitwisseling zonder blokkades/mutexen in de meeste gevallen garandeert.
Stack van een goroutine:
- Aanvankelijk zijn de stacks van goroutines klein, meestal 2 KB (voor Go 1.4 was dat 4 KB).
- De stack groeit en krimpt dynamisch. Bij overflow wordt deze automatisch uitgebreid, en bij vrijmaken van geheugen wordt deze verkleind.
- Dit dynamische stackbeheer vermindert de kosten vergeleken met grote vaste stacks van OS-threads.
Geheugenverbruik op de stack:
- Bij creatie neemt een goroutine meestal 2 KB geheugen in beslag voor zijn stack.
- Het geheugenverbruik kan dynamisch toenemen bij functieaanroepen en afnemen bij terugkeer.
- De maximale stackgrootte is beperkt, maar groot genoeg voor de meeste taken (meestal enkele MB).
package main
import (
"fmt"
"runtime"
"time"
)
func sayHello() {
fmt.Println("Hallo vanaf een goroutine!")
}
func main() {
// Demonstratie van het maken van een goroutine
go sayHello()
// Om het werk van de goroutine te observeren
time.Sleep(100 * time.Millisecond)
fmt.Printf("Aantal goroutines: %d\n", runtime.NumGoroutine())
}
In dit voorbeeld wordt sayHello uitgevoerd als een aparte goroutine. runtime.NumGoroutine() toont het aantal actieve goroutines (inclusief de hoofd).