Abstract
The Go language is a powerful tool based mainly on two components: the Go compiler, which transforms our code into an executable binary, and the runtime, a big chunk of existing code compiled with our code. This talk is about the later, that piece of software that includes things like the garbage collector, the scheduler, goroutines, maps, channels...
In this talk, we will go through the explanation of what is the Go runtime and what it contains. Also, we'll talk about all the initialization processes and what does for us the runtime once everything is initialized and our code is running.
We will talk about the garbage collector and scheduler initialization, the spawn of our main function in a Go routine, and a shallow explanation of things that happen after that, like goroutines scheduling and memory management.
The talk script
Introduction
I will start by explaining what the Go runtime at a general level is, what it does (memory management, concurrency, builtin data structures...), and the cost of having it (bigger binaries, slightly slower startup process than other compiled languages, some extra runtime cost...)
Once we have settled on a general view of the runtime, I will start from the beginning, where is the Go runtime code and how it gets into our binaries. How the linking process includes our Go program plus the go runtime.
Deep dive in the initialization
After that, we going to start analyzing what happens at runtime from the exact moment the binary starts to execute until it reaches the main function.
This is the meaty part of the talk, here I going to talk about:
- The assembly code that triggers execution
- The initialization based on the operating system
- The scheduler initialization
- The heap/stack initialization
- The garbage collector initialization
- And some other small initialization bits here and there.
Here I'll cover in a certain degree of detail what implies all this initialization and why they are needed.
Deep dive in the running process
After that, we will talk about this first goroutine that will be created for our main function. I'll give a light overview of what a goroutine is and its creation process. And how it gets the goroutine for main created and executed.
Once we have our main function running, I want to explore some other things that happen while our binary is running, things like the garbage collections, goroutines parking (and preemption), and some things that are defined as part of the runtime, like maps, slices, and channels...
Finally, I'll quickly show what happens when our binary finishes its execution.
Just a quick summary of everything we have seen, some conclusions, and references to keep investigating.