Golang's memory management model is based upon tcmalloc pattern. TCMalloc is Google's customized implementation of c's
malloc and c++'s
operator new used for memory allocation within c or c++ code. We know that
malloc invoked will trigger threads switch into kernel space, it's a big consumption. So TCMalloc provide thread cache capability to enhance the performance. In golang, the local cache is not specify to thread, but P, processors in GMP schedule Model.
To make a high performance memory manage system, what functions do we need to ensure efficient?
There are 3 types of memory manager:
mheap in Golang. They are implemented based on the GMP pattern, introduced before, to provide high performance feature. Objects, little that 32 kb is allocated from mcentral, greater than 32 kb is rounded up to page size, and page is directly allocated from heap.
mcache is bind to
P in GMP pattern. It means that mcache is used for every goroutine to allocate memory. It handles a list of span(memory chunk of 32kb), called
mspan, that contains the memory available for allocation:
allocation with mcache
There is no lock in mcache struct, because every P is bound separated and every P only handle for one goroutine at a time, and memory access is isolated. Using this local cache does not require lock and makes the allocation more efficient
The span list is divided into about 70 size classes. from 8 bytes to 32k bytes. Each span exists twice: one list is for objects that contain pointer and the other one is not contains pointer. This distinction will make the life of the garbage collector easier since it will not have to scan the spans that do not contains any pointer.
span size of classes
If we need allocate an object of 32 bytes. the allocator will find the span with size of 32 bytes and fit the object in the 32 bytes span:
fit in the 32 bytes span
Now you must wonder what will happen if the span does not have a free slot during the allocation. Go maintains central list of spans per size classes, named
mcentral, with the spans that contain free objects and the one that do not:
central list of spans
mcentral maintains a double linked list of spans. Each of them has a reference to previous span and next span. A span in non-empty list means that there at least one slot is free in the list allocation, even some slot is in-use already. Indeed, when the garbage collector sweeps the memory, it could clean a part of the span, the part that marked as not used anymore, and also, the span will be put back to the non-empty list.