01 Local cache for P: mcache
|
|
nextSmaple
triggers a heap instance after allocating this many bytes.mcache
is not in GC scope, so it needs to be released manually withmache.releaseAll()
.tiny
is a heap pointer to a cache of small objects.tinyAllocs
is the number of small object allocations that have been requested by the host P.tinyoffset
is the offset, i.e. location, of where the current small object is located.alloc
is a cut up of small objects of different small sizesmspan
. There are_NumSizeClasses=67
, which means there are 67 different sizes ofmspan
objects. The reason whynumSpanClasses = _NumSizeClasses << 1
is that eachspanclass
contains two types, ascan
and anoscan
. For the object where the memory is allocated, if it does not contain a pointer, it is put intonoscan
, otherwise it is put intoscan
. Because those that do not contain pointers do not need to be scanned by GC.
|
|
stackcache
is the definition of stack size rules, there are _NumStackOrders
in total. The stack size varies from OS to OS.
flushGen
is used for cleanup and refresh.
In summary, the overall memory allocation model for P is as follows.
Each P has its own cached memory allocation management object mcache
. Each mcache
holds n sliced and diced mspan
Doubly linked list of different sizes, and stack space stackfreelist
of different sizes. The existing memory requests on the mcache are exclusively occupied by the current P. The request process does not require locking, so its efficiency is high.
02 Small object storage structure: mspan
|
|
The mspan
object fields are very numerous. next
and prev
are pointers to the front and back of the Doubly linked list.
-
startAddr
is the memory address pointing to the beginning of the chain. -
npages
is an indication of the size of the specification ofmspan
in pages. Pages are the smallest unit of memory that Golang requests from the operating system, currently designed to be 8KB. -
spanclass
indicates the specification type ofmspan
. -
allocBits
is a bitmap of the currentmspan
requests, recording which places have been requested and which are free. -
gcmarkBits
indicates which objects inmspan
have been freed. -
freeindex
between 0 ~ nelems
, i.e. afterfreeindex
is the index of the free requestable subscript. The rules for each allocation are as follows.Start from n>freeindex, i.e. from allocBits[n], to see if there is enough free capacity after it.Calculate whether allocBits[n/8] & (1 « (n % 8)) is 0, if it is 0, it means it can be applied, otherwise it means there are no more resources for the current span.
-
nelems
is the number of objects inmspan
.
03 Global memory cache mcentral
mcentral
is designed to be able to allocate memory even if p’s local mcache
is insufficient. mcentral
is a centralized memory allocation center where all p’s can request memory from mcentral
, which involves data contention and requires locking, so it is not as efficient as mcache
.
mcentral
, likemcache.mspans
, is also subspecified, and amcentral
maintains only one size of memory request. Specified byspanclass
.partial
is the list of all freespan
s maintained bymcentral
itself.full
is the list ofspan
s maintained bymcentral
for which non-freespan
s exist.
In general, the structure of mcentral
is as above. Each mcentral
object maintains a list of mspan
s of only one size. When a p’s mcache
does not have enough memory, it requests the mcentral
of the specified specification, and this process adds a lock. The mcentral
then prioritizes picking one from the non-full free list full
, otherwise it goes to partial
and picks one to allocate to the application.
04 Heap memory: mheap
For both mcache
and mcentral
, neither can maintain memory blocks larger than 32KB, so for large memory is allocated directly on the heap, while mcentral
will also replenish memory blocks via mheap
. This process still requires locking to secure the data.
|
|
- On
heapArena
, the maintenance granularity is 64MB (64bit OS). - On
mheap
, the minimum maintenance granularity is page (1page=8KB).
05 Summary
- The heap in Golang is composed of a block of memory, represented as
heapArena
in runtime, each block is 64MB in size and consists of many pages, with one page occupying 8KB of space (at 64bit). mheap
is the management object of the memory block, which is managed according to the page granularity.mcentral
is a further management of the pages in mheap, and because it is global, access requires locking. Eachmspan
specification corresponds to onemcentral
for management. Eachmcentral
has twomspan
lists, one for unused and one for used.- A cache
mcache
of the P itself is maintained inside each P. Themcache
also maintains a list of 67 different specifications ofmspan
, each of which is stored in an array. One specification corresponds to two elements of the array, one storing pointer objects and one storing non-pointer objects.mcache
itself is exclusive to P, so no locking application is required. - When requesting memory in a program (such as
make
, ornew
, etc.), the P corresponding to the g where it is located will first request it from its ownmcache
, and if there is not enough space, it will request it frommcentral
, and if there is still none, it will continue to request it frommheap
. - Since the specification of
mspan
is only from 1Byte to 32KB, for objects over 32KB, it will apply tomheap
directly. - Golang’s memory allocation uses multi-level caching to reduce lock granularity for more efficient memory allocation. When recycling objects, the memory is not recycled directly, but put back into pre-allocated memory blocks, and only returned to the OS when there is too much free memory.