The Scheduler | Internals for Interns

In the previous article we explored how Go’s memory allocator manages heap memory — grabbing large arenas from the OS, dividing them into spans and size classes, and using a three-level hierarchy (mcache, mcentral, mheap) to make most allocations lock-free. A key detail was that each P (processor) gets its own memory cache. But we never really explained what a P is, or how the runtime decides which goroutine runs on which thread. That’s the scheduler’s job, and that’s what we’re exploring today.

Internals for Interns
The Memory Allocator | Internals for Interns

In the previous article we explored how the Go runtime bootstraps itself — how a Go binary goes from the operating system handing it control to your func main() running. During that bootstrap, one of the first things the runtime sets up is the memory allocator. And that’s what we’re going to explore today. Think of the memory allocator as a warehouse manager. Your program constantly needs boxes of different sizes — sometimes tiny, sometimes huge — and it needs them fast. The allocator’s job is to hand out those boxes as quickly as possible, keep the warehouse organized so nothing goes to waste, and work with the garbage collector to reclaim boxes that nobody is using anymore.

Internals for Interns