01 Local cache for P: mcache
|
|
nextSmapletriggers a heap instance after allocating this many bytes.mcacheis not in GC scope, so it needs to be released manually withmache.releaseAll().tinyis a heap pointer to a cache of small objects.tinyAllocsis the number of small object allocations that have been requested by the host P.tinyoffsetis the offset, i.e. location, of where the current small object is located.allocis a cut up of small objects of different small sizesmspan. There are_NumSizeClasses=67, which means there are 67 different sizes ofmspanobjects. The reason whynumSpanClasses = _NumSizeClasses << 1is that eachspanclasscontains two types, ascanand 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.
flushGenis 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.
-
startAddris the memory address pointing to the beginning of the chain. -
npagesis an indication of the size of the specification ofmspanin pages. Pages are the smallest unit of memory that Golang requests from the operating system, currently designed to be 8KB. -
spanclassindicates the specification type ofmspan. -
allocBitsis a bitmap of the currentmspanrequests, recording which places have been requested and which are free. -
gcmarkBitsindicates which objects inmspanhave been freed. -
freeindexbetween 0 ~ nelems, i.e. afterfreeindexis 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.
-
nelemsis 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 amcentralmaintains only one size of memory request. Specified byspanclass.partialis the list of all freespans maintained bymcentralitself.fullis the list ofspans maintained bymcentralfor which non-freespans exist.
In general, the structure of mcentral is as above. Each mcentral object maintains a list of mspans 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
heapArenain runtime, each block is 64MB in size and consists of many pages, with one page occupying 8KB of space (at 64bit). mheapis the management object of the memory block, which is managed according to the page granularity.mcentralis a further management of the pages in mheap, and because it is global, access requires locking. Eachmspanspecification corresponds to onemcentralfor management. Eachmcentralhas twomspanlists, one for unused and one for used.- A cache
mcacheof the P itself is maintained inside each P. Themcachealso 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.mcacheitself 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
mspanis only from 1Byte to 32KB, for objects over 32KB, it will apply tomheapdirectly. - 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.