Go语言内置运行时,就是runtime, 抛弃了传统的内存分配方式,改为自主管理,这样可以自主地实现更好的内存使用模式,比如说内存池,预分配等等。这样,就不会每次内存分配都需要进行系统调用。

Golang运行时的内存分配算法主要源自Gppgle为C语言开发的TCMalloc算法,全称为Thread Caching Malloc。核心思想就是把内存分为多级管理,从而降低锁的粒度。它将可用的堆内存采用二级分配的方式进行管理。每个线程都会维护一个独立的内存池,进行内存分配时,优先从该内存中分配。当内存池不足时才会向全局内存池申请,以避免不同线程对全局内存池的频繁竞争。

基础概念

Go在程序启动的时候,会先向操作系统申请一块内存。注意这时候只是一块虚拟的地址空间,并不会真正地分配内存,切成小块后自己进行管理。

image.png
这一part太烧脑了,先跳过

内存管理组件

Mheap, MCache, MCentral的关系

  1. Mheap是一个全局变量,负责向系统申请内存,mallocinit()函数进行初始化。如果分配内存对象大于32K直接向Mheap申请
  2. MCache管理线程级(协程),关联结构体P, 主要负责线程内部内存的申请。他是实现goroutine高并发的重要因素,因为分配小对象可直接从MCache中分配,不用加锁,提升了并发效率。
  3. MCentral是连接Mheap与MCache的,MCache内存不够则向MCentral申请,MCentral不够时向MHeap申请内存

参考

Golang内存管理机制
图解Go语言内存分配
可视化Go内存管理