- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
Golang内存管理机制
golang是⼀门⾃带垃圾回收的语⾔,它的内存分配器和tmalloc(thread-caching malloc)很像,⼤多数情况下是不需要⽤户⾃⼰管理内存的。
最近了解了⼀下golang内存管理,写出来分享⼀下,不正确的地⽅请⼤佬们指出。
那么,如果⾃⼰想要实现⼀门语⾔的内存管理,应该怎么设计呢?
1.内存池:
应该有⼀个主要管理内存分配的部分,向系统申请⼤块内存,然后进⾏管理和分配。
2.垃圾回收:
当分配的内存使⽤完之后,不直接归还给系统,⽽是归还给内存池,⽅便进⾏下⼀次复⽤。⾄于垃圾回收选择标记回收,还是分代回收算法
应该符合语⾔设计初衷吧。
3.⼤⼩切分:
使⽤单独的数组或者链表,把需要申请的内存⼤⼩向上取整,直接从这个数组或链表拿出对应的⼤⼩内存块,⽅便分配内存。⼤的对象以页
申请内存,⼩的对象以块来申请,避免内存碎⽚,提⾼内存使⽤率。
4.多线程管理:
每个线程应该有⾃⼰的内存块,这样避免同时访问共享区的时候加锁,提升语⾔的并发性,线程之间通信使⽤消息队列的形式,⼀定不要使
⽤共享内存的⽅式。提供全局性的分配链,如果线程内存不够⽤了,可向分配链申请内存。
这样的内存分配设计涵盖了⼤部分语⾔的,上⾯的想法其实是把golang语⾔内存分配抽象出来。其实Java语⾔也可以以同样的⽅式理解。内
存池就是JVM堆,主要负责申请⼤块内存;多线程管理⽅⾯是使⽤栈内存,每个线程有⾃⼰独⽴的栈内存进⾏管理。
golang 内存分配器
golang内存分配器主要包含三个数据结构:MHeap,MCentral以及MCache
1.MHeap:分配堆,主要是负责向系统申请⼤块的内存,为下层MCentral和MCache提供内存服务。他管理的基本单位是MSpan(若⼲连续内
存页的数据结构)
type MSpan struct
{
MSpan *next;
MSpan *prev;
PageId start; // 开始的页号
uintptr npages; // 页数
…..
};
可以看出MSpan是⼀个双端链表的形式,⾥⾯存储了它的⼀些位置信息。
通过⼀个基地址+(页号*页⼤⼩),就可以定位到这个MSpan的实际内存空间。
type MHeap struct
{
lock mutex;
free [_MaxMHeapList] mSpanList // free lists of given length
freelarge mSpanList // free lists length = _MaxMHeapList
busy [_MaxMHeapList] mSpanList // busy lists of large objects of given length
busylarge mSpanList
};
free数组以span为序号管理多个链表。当central需要时,只需从free找到页数合适的链表。large链表⽤于保存所有超出free和busy页数限制
的MSpan。
MHeap⽰意图:
2.MCache:运⾏时分配池,不针对全局,⽽是每个线程都有⾃⼰的局部内存缓存MCache,他是实现goroutine⾼并发的重要因素,因为分配
⼩对象可直接从MCache中分配,不⽤加锁,提升了并发效率。
type MCache struct
{
tiny byte*; // Allocator cache for tiny objects w/o pointers.
tinysize uintptr;
alloc[NumSizeClasses] MSpan*; // spans to allocate from
};
尽可能将微⼩对象组合到⼀个tiny块中,提⾼性能。
alloc[]⽤于分配对象,如果没有了,则可以向对应的MCentral获取新的Span进⾏操作。
线程中分配⼩对象(16~32K)的过程:
对于 size 介于 16 ~ 32K byte 的内存分配先计算应该分配的 sizeclass,然后去 mcache ⾥⾯ alloc[sizeclass] 申请,如果
mcache.alloc[sizeclass] 不⾜以申请,则 mcache 向 mcentral 申请mcentral 给 mcache 分配完之后会判断⾃⼰需不需要扩充,如果需要则想
mheap 申请。
每个线程内申请内存是逐级向上的,⾸先看MCache是否有⾜够空间,没有就像MCentral申请,再没有就像MHea
您可能关注的文档
最近下载
- 粗轧机AWC液压控制系统故障原因分析和改进.pdf VIP
- 2025年中国银行社会招聘备考试题及答案解析.docx VIP
- 《草原》部编版 六年级上册语文PPT课件.ppt VIP
- 市属投资集团公司下属企业工资总额预算管理办法.pdf VIP
- 2025中国银行社会招聘考试备考题库及答案解析.docx VIP
- 2025中国银行新疆区分行社会招聘笔试模拟试题及答案解析.docx VIP
- 2025中国银行新疆区分行社会招聘笔试参考题库附答案解析.docx VIP
- 2025年叉车司机(技师)职业技能鉴定理论考试题库资料(含答案).pdf
- 2025中国银行新疆区分行招聘82名工作人员笔试备考试题及答案解析.docx VIP
- 大模型时代的具身智能.pptx
文档评论(0)