Understanding the Linux Kernel: Memory Manager

In the previous article
we looked at how a user program crosses the ring 3 → ring 0 boundary to ask the kernel for help. The example we used was read() — a file descriptor, a buffer pointer, a byte …
Welcome! This is a blog about how things work under the hood. If you’ve ever wondered what happens when your code runs, how databases execute queries, or what compilers do with your source code, you’re in the right place.
I write deep dives into software internals—covering programming languages, compilers, databases, filesystems, and more—but with a twist: I aim to make complicated internal behaviors look simple. These aren’t exhaustive references; they’re approachable overviews that give you just enough understanding to appreciate the clever engineering behind the tools you use every day.
What to expect: Posts here explore topics like Go’s compiler phases (lexer, parser, SSA), Python’s object model and garbage collection, database query execution, filesystem structures, and runtime behaviors like memory allocation and goroutines. Each post takes a concrete example (like a “hello world” program) and walks through what happens internally.
Publishing cadence: I publish a new post every week, diving deep into a different aspect of software internals with each article.
Whether you’re a student, an intern, or a seasoned developer curious about the internals you don’t usually need to think about, I hope these posts give you those “aha!” moments that make programming even more fascinating.

In the previous article
we looked at how a user program crosses the ring 3 → ring 0 boundary to ask the kernel for help. The example we used was read() — a file descriptor, a buffer pointer, a byte …

In the previous article
we took apart the select statement and saw how it’s really two features in one, with the compiler rewriting the easy shapes away and only the hard cases falling through …

In the previous article
we followed the kernel from the very first instruction the bootloader handed us all the way to the moment kernel_init called execve() on /sbin/init. That was a long ride, but …

In the previous article we walked through slices, maps, and channels, and how each of them is structured under the hood. Out of those three, channels are probably the most involved one in terms of …

Have you ever wondered what really happens between the moment you press the power button and the moment your login screen shows up? That gap—usually some seconds—hides one of the most intricate …

So far in this series we’ve looked at the parts of the Go runtime that orchestrate execution — the memory allocator, the scheduler, the garbage collector, sysmon, the netpoller. Today …

In the previous article , we explored Btrfs—a copy-on-write filesystem built around a single kind of B-tree, where every file, extent, checksum and chunk mapping lives as a tagged item in some tree, …

In the previous article
we saw how sysmon steps in every 10ms to call netpoll(0) on behalf of busy Ps, making sure network I/O doesn’t stall when the scheduler is too busy to poll on its own. …

In the previous article , we explored XFS—a filesystem built for extreme scale that divides the disk into independent Allocation Groups, each with its own B+ trees for free space, inodes, and extent …

In the previous articles we explored the scheduler — how goroutines get multiplexed onto OS threads through the GMP model — and the garbage collector — how Go tracks and reclaims memory using a …