基于 Go 1.14
Golang 的内存分配器借鉴了 TCMalloc,在多级缓存的基础上,根据对象大小所属类别,实施不同分配策略。
内存管理
管理组件
- 内存管理单元
runtime.mspan
:Go 语言内存管理的基本单元,管理多个页- 页大小:8KB
- 线程缓存
runtime.mcache
:与线程上的处理器一一绑定,无需锁 - 中心缓存
runtime.mcentral
:需要锁 - 页堆
runtime.mheap
:一个 Go 语言程序只会存在一个全局的页堆
管理
从线程缓存到操作系统内存,遵循一种模式: * 如果在当前内存管理组件获取不到可用内存,则会向下一级组件申请内存并进行扩容 * 如果最后到操作系统都申请不到内存的话,则说明宿主机上内存耗尽,程序会终止。
内存分配
堆上所有的对象都会通过 runtime.newobject()
来分配内存。
根据申请对象的大小执行不同的策略: * 微对象 0 < size < 16B
:线程缓存中的微对象分配器 ——> 线程缓存 ——> 中心缓存 ——> 页堆 * 小对象 16B <= size <= 32KB
:线程缓存 ——> 中心缓存 ——> 页堆 * 大对象 size > 32KB
:直接在堆上进行分配