求剧情
Go语言学习笔记 · 第十一节

《Go语言学习笔记》第十一节

本节介绍Go语言内存分配器的结构与工作流程。分配器管理的内存分为span(内部管理)和object(面向分配)两种。

本节介绍Go语言内存分配器的结构与工作流程。分配器管理的内存分为span(内部管理)和object(面向分配)两种。span按页数存入管理数组,找不到合适大小时返回更大页数的span并裁剪,多余部分放回,同时合并相邻空闲span以减少碎片。object按8字节倍数分成若干规格(sizeclass),微小对象会组合进同一object块以节约内存;超出阈值的对象作为大对象直接处理。分配器由mheap、mcentral、mcache三种组件构成。

分配流程为:先确定对象规格,从线程私有的cache中找同规格span,从其freelist取object;span为空则向central取新span;central也无空闲则从heap取并切分;heap也没有则用mmap向操作系统申请新内存。释放时object归还span,span放回central供其他cache复用,全部收回的span交还heap重新切分,长期闲置的span会被定期释放。

初始化时会预留一大段虚拟地址空间,划分为arena(实际申请内存)、bitmap(记录指针与GC标记)、spans(按页对应span)三个区域,三者可按需同步线性扩张。保留地址并不等于分配内存,物理内存在写操作触发缺页时才按页分配。编译器通过逃逸分析与内联优化决定对象分配在栈还是堆上,使用new未必导致堆分配。

‹ 上一章目录下一章 ›

全部 17 章