GO的内存分配大致了解 | 青训营笔记

82 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 4 天

Go语言内置运行时(就是runtime),抛弃了传统的内存分配方式,改为自主管理,最开始是基于tcmalloc,虽然后面改动相对已经很大了。使用自主管理可以实现更好的内存使用模式,比如内存池、预分配等等,从而避免了系统调用所带来的性能问题。

Go的内存分配的大致流程如下

  1. 首先判定 对象是 大对象 还是 普通对象还是 小对象

  2. 如果是 小对象

    1. 从 mcache 的alloc 找到对应 classsize 的 mspan
    2. 如果当前mspan有足够的空间,分配并修改mspan的相关属性(nextFreeFast函数中实现)
    3. 如果当前mspan没有足够的空间,从 mcentral重新获取一块 对应 classsize的 mspan,替换原先的mspan,然后 分配并修改mspan的相关属性
    4. 如果mcentral没有足够的对应的classsize的span,则去向mheap申请
    5. 如果 对应classsize的span没有了,则找一个相近的classsize的span,切割并分配
    6. 如果 找不到相近的classsize的span,则去向系统申请,并补充到mheap中
  3. 如果是普通对象,逻辑大致同小对象的 内存分配

    1. 首先查表,以确定 需要分配内存的对象的 sizeclass,并找到 对应 classsize的 mspan
    2. 如果当前mspan有足够的空间,分配并修改mspan的相关属性(nextFreeFast函数中实现)
    3. 如果当前mspan没有足够的空间,从 mcentral重新获取一块 对应 classsize的 mspan,替换原先的mspan,然后 分配并修改mspan的相关属性
    4. 如果mcentral没有足够的对应的classsize的span,则去向mheap申请
    5. 如果 对应classsize的span没有了,则找一个相近的classsize的span,切割并分配
    6. 如果 找不到相近的classsize的span,则去向系统申请,并补充到mheap中
  4. 如果是大对象,直接从mheap进行分配

    1. 如果 对应classsize的span没有了,则找一个相近的classsize的span,切割并分配
    2. 如果 找不到相近的classsize的span,则去向系统申请,并补充到mheap中

参考引用:深入理解Go-内存分配 - go学习 - SegmentFault 思否