A deep dive into the internal memory layouts of Go's three most common built-in types: slices, maps, and channels. Slices are 24-byte headers (array pointer, len, cap) over a heap-allocated backing array that doubles on growth until 256 elements then transitions to 1.25x growth. Maps since Go 1.24 use Swiss Tables organized as a three-level hierarchy: a header pointing to a directory of tables, each table holding groups of 8 slots with an 8-byte control word enabling fast SIMD-style lookups via H2 hash previews; growth is local, only rehashing the overflowing table. Channels are hchan structs with a circular buffer and two doubly-linked queues of sudog structs for parked goroutines; when a sender meets a waiting receiver the value is copied directly between goroutines, bypassing the buffer entirely. Common pitfalls like shared backing arrays in sub-slices and the tombstone vs empty distinction in map deletion are explained with concrete examples.

31m read timeFrom internals-for-interns.com
Post cover image
Table of contents
SlicesMapsChannelsSummary
1 Comment

Sort: