Go语言的内存管理是一个复杂的过程,它采用了多级缓存机制来提高内存分配的效率。以下是Go内存分配的基本概念和流程:
Page: Go内存管理中,内存被分割成固定大小的页,通常是8KB。
Span: 一组连续的页被称为Span,是内存管理的基本单位。
mcache: 每个逻辑处理器(P)都有一个mcache,它是一个线程本地缓存,用于存储小对象(小于等于32KB)。mcache中包含了多种大小类别的mspan,用于快速分配内存。
mcentral: 类似于TCMalloc中的CentralCache,是所有线程共享的缓存,负责管理不同大小类别的Span。当mcache中的某个Span被用完时,会向mcentral申请新的Span。
mheap: 管理整个进程的堆内存,包括大对象的分配和未切割的Span的管理。
内存分配流程如下:
- 对于小于16字节的微小对象,使用mcache的Tiny分配器进行分配。
- 对于16字节到32KB之间的小对象,首先计算对象的Size Class,然后从mcache中对应Size Class的mspan进行分配。如果mcache中没有足够的mspan,会向mcentral申请,如果mcentral也没有,再向mheap申请。
- 对于大于32KB的大对象,直接在mheap上进行分配。
垃圾回收(GC)在Go中也是一个重要的部分,它通过标记-清除算法来识别和回收不再使用的对象,以避免内存泄漏。
这些信息主要基于Go 1.13版本,但大部分概念在后续版本中仍然适用。