- 1、本文档共154页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
Go 学习笔记第二部分 源码
Go 学习笔记第⼆部分 源码
第⼆部分 源码
基于 Go 1.4 ,相关⽂件位于 src/runtime ⽬录。⽂章忽略了 32bit 代码,有兴趣的可⾃
⾏查看源码⽂件。为便于阅读, 例代码做过裁剪。
1. Memory Allocator
Go 内存分配器基于 tcmalloc 模型,这在 malloc .h 头部注释中有明确说明。
Memory allocator, based on tcmalloc.
/doc/tcmalloc.html
核⼼⽬标很简单:
从 mmap 申请⼤块内存,⾃主管理,减少系统调⽤。
基于块的内存复⽤体系,加快内存分配和回收操作。
分配器以页为单位向操作系统申请⼤块内存。这些⼤块内存由 n 个地址连续的页组
成,并⽤名为 span 的对象进⾏管理。
malloc .h
PageShift = 1 ,
PageSize = 1PageShift, // 8192 bytes
当需要时,span 所管理内存被切分成多个⼤⼩相等的⼩块,每个⼩块可存储⼀个对
象,故称作 object 。
分配器以 32KB 为界,将对象分为⼤⼩两种。
malloc .h
MaxSmallSize = 210,
⼤对象直接找⼀个⼤⼩合适的 span ,这个⽆需多⾔。⼩对象则以 8 的倍数分为不同⼤
⼩等级 (size class) 。⽐如 class1 为 8 字节,可存储 1 ~ 8 字节⼤⼩的对象。
NumSizeClasses = 67,
当然,实际的对应规则并不是连续和固定的,会根据⼀些经验和测试结果进⾏调整,
以获得最佳的性能和内存利⽤率。
malloc .h
// Size classes. Computed and initialized by InitSizes.
//
// SizeToClass(0 = n = MaxSmallSize) returns the size class,
// 1 = sizeclass NumSizeClasses, for n.
// Size class 0 is reserved to mean not small.
//
// class_to_size[i] = largest size in class i
// class_to_allocnpages[i] = number of pages to allocate when
// making new objects in class i
int 2 runtime·SizeToClass(int 2);
externint 2 runtime·class_to_size[NumSizeClasses];
externint 2 runtime·class_to_allocnpages[NumSizeClasses];
externint8 runtime·size_to_class8[1024/8 + 1];
externint8 runtime·size_to_class128[(MaxSmallSize-1024)/128 + 1]
为了管理好内存,分配器使⽤三级组件来完成不同操作。
heap 全局根对象。负责向操作系统申请内存,管理由垃圾回收器收回的空闲
span 内存块。
central 从 heap 获取空闲 span ,并按需要将其切分成 object 块。heap 管理着多
个central 对象,每个 central 负责处理⼀种等级的内存分配需求。
cache 运⾏期,每个 cache 都与某个具体线程相绑定,实现⽆锁内存分配操
作。其内部有个以等级为序号的数组,持有多个切分好的 span 对象。缺少空间
时,向等级对应的 central 获取新的 span 即可。
简单描述⼀下内存分配和回收流程。
分配流程:
通过 size class 反查表计算待分配对象等级。
从 cache .alloc[sizeclass] 找到等级相同的 span 。
从 span 切分好的链表中提取可⽤ object 。
如 span 没剩余空间,则从 heap .central[sizeclass] 找到对应 central ,获取 span 。
如 central 没可⽤ span ,则向 heap 申请,
文档评论(0)