takeaway


This article is based on Go source version 1.16, 64-bit Linux platform, 1Page=8KB, this article's memory refers to virtual memoryCopy the code

Today we begin chapter 2 of the Go Easy series, “Memory and Garbage Collection,” part 2, “Go Memory Management.”

The chapter on memory and garbage Collection is divided into three sections:

  • Knowledge before Reading (finished)
    • Pointer size
    • Linear allocation of memory
    • What is a FreeList?
    • Virtual memory
    • TCMalloc memory allocation principle
  • Go Language Memory Management (current section)
  • Go language garbage collection principle (not started)

The first part, “Knowledge before reading”, has been completed. For better understanding of this article, you can click on the history link to view or review it.

directory


My thoughts about explaining “Go language memory management” are as follows:

  1. Introduction to the Overall Architecture
  2. Introduces an interesting aspect of architectural design
  3. By introducing the key structure of Go memory managementmspanAnd out of thepage,mspan,object,sizeclass,spanclass,heaparena,chunkThe concept of
  4. Then introduce heap memory, stack memory allocation
  5. Review and summary

Directories dismantled by this thread:

  • Go Memory Management Architecture
    • mcache
    • mcentral
    • mheap
  • Why thread cachingmcacheIs the logical processorpHolds, rather than system threadsm?
  • Go Memory management unitmspan
    • pageThe concept of
    • mspanThe concept of
    • objectThe concept of
    • sizeclassThe concept of
    • spanclassThe concept of
    • heaparenaThe concept of
    • chunkThe concept of
  • Go heap memory allocation
    • Microobject allocation
    • Small object allocation
    • Large object allocation
  • Go stack memory allocation
    • Stack memory allocation timing
    • Stack allocation less than 32KB
    • Stack allocation greater than or equal to 32KB

Go memory management architecture


Go’s memory is managed by a unified memory manager, which is designed and implemented based on Google’s own open source TCMalloc memory allocator. A detailed description of the TCMalloc memory allocator can be found in previous articles.

Let’s start with a brief review of the core design of the TCMalloc memory allocator.

reviewTCMallocMemory allocator

The background of TCMalloc’s birth?

In the multi-core and hyper-threading era, multi-threading technology has been widely used in various programming languages. When using multi-threading technology, due to multi-threading shared memory, threads will compete in memory (virtual memory), due to the parallelism problem will generate race insecurity.

To ensure the security of memory allocation, locks must be added to the process of memory allocation, which may cause congestion and affect performance. The TCMalloc memory allocator was born and opened source.

How does TCMalloc solve this problem?

Alloc Thread Cache Memory allocator. As the name implies, memory caching is added to threads to reduce contention and improve performance. When threads run out of memory, they lock to acquire memory from shared memory.

Then let’s look at the architecture of TCMalloc.

TCMalloc’s architecture?

TCMalloc three-tier logical architecture

  • ThreadCache: thread cache
  • CentralFreeList(CentralCache) : CentralCache
  • PageHeap: heap memory

How do the different layers on the TCMalloc architecture collaborate?

TCMalloc divides the applied memory objects into two categories according to their sizes:

  • Small object <= 256 KB
  • Large object > 256 KB

For example, when allocating memory to a small object:

  • Go to the thread cache firstThreadCacheThe distribution of
  • When threads are cachedThreadCacheWhen the memory is insufficient, from the correspondingSizeClassThe central cache ofCentralFreeListTo obtain
  • And then finally, from the correspondingSizeClassthePageHeapThe distribution of

Logical architecture of the Go memory allocator

Using the same three-tier logic architecture as the TCMalloc memory allocator:

  • mcache: thread cache
  • mcentral: Central cache
  • mheap: heap memory

The actual central cache is an array of 136 elements of type McEntral.

One more thing to note: The McAche is held by the logical processor P, not by the actual system thread M. (This is an interesting design and will be explained in a future article.)

We update the architecture diagram as follows:

The Go memory allocator divides the requested memory objects into three categories by size:

  • Micro Object 0 < Micro Object < 16B
  • Small Object 16B =< Small Object <= 32KB
  • Large Object 32KB < Large Object

To see the relationship between these three levels clearly, here is an example of allocating small objects on the heap:

  • Go to the thread cache firstmcacheAllocate memory in
  • If you can’t find it, go to central cachecentralAllocate memory in
  • And then you go straight to the pilemheapAllocate a block of memory

Architecture to summarize


Through the above analysis, it can be seen that the design of Go memory allocator is basically consistent with the concept and thinking of open source TCMalloc memory allocator. The comparison diagram is as follows:

Finally, we conclude:

  • The Go memory allocator uses andTCMallocSame three-tier architecture. Logically:
    • mcache: thread cache
    • mcentral: Central cache
    • mheap: heap memory
  • The thread cachemcacheIs the logical processorpHolds, rather than system threadsm

Check out the Go Easy Progression series for more


Link tigerb. Cn/go / # / kernal…