面试题答案
一键面试内存分配基本策略
- 基于伙伴系统的堆内存管理:Go语言的堆内存管理采用基于伙伴系统(Buddy System)的算法。它将堆内存划分为不同大小的块,每个块可以与相同大小的“伙伴”块合并成更大的块,也可以从大的块分裂成小的块,以此来高效地管理内存的分配和释放。
- 缓存机制:为了提高内存分配的效率,Go语言使用了多级缓存机制。其中包括线程缓存(TCMalloc中的Thread - Local Cache类似概念),每个运行时线程都有自己的缓存。当进行内存分配时,优先从线程缓存中分配,如果缓存不足,再从堆中获取。这样减少了多线程环境下对堆内存的竞争,提高了分配效率。
对象大小对分配方式的影响
- 小对象(小于等于32KB):
- 对于小于等于8字节的对象,Go语言会将它们分配到特定的微小对象分配区域(tiny allocator)。这些对象不会被单独分配内存块,而是会被打包存放在一个大块中,以节省空间和提高分配效率。
- 对于大于8字节且小于等于32KB的对象,会根据对象大小从预定义的不同大小类别的内存块中进行分配。这些内存块来自线程缓存,若线程缓存中没有合适大小的块,则从堆中获取合适大小的块划分后放入线程缓存,再进行分配。
- 大对象(大于32KB):大对象会直接在堆上分配内存,并且绕过线程缓存。因为大对象占用空间大,如果放在线程缓存中,会对缓存的利用率产生较大影响,且大对象分配频率相对较低,直接在堆上分配可以简化分配逻辑,避免对缓存管理造成压力。