Go堆内存管理

发布于:2024-07-05 ⋅ 阅读:(18) ⋅ 点赞:(0)

内存管理单元

内存管理单元有如下

  • page: x64下大小为8k。go与OS内存申请与释放都是以page为单位

  • span: 多个连续page组成,是内存管理的基本单元

  • mcache: 每个P所有的cache,包含多个空闲内存块链表,不同的链表上的内存块大小可能是不相同的

  • mcentral: 是所有线程共享的缓存,需要加锁访问。按 Span class 对 Span 分类,串联成链表,当 mcache 的某个级别 Span 的内存被分配光时,它会向 mcentral 申请 1 个当前级别的 Span

  • heapArena: heapArena 是由 mheap 管理的更小的内存块。整个堆内存被划分为多个 heapArena,每个 heapArena 通常是 64MB(在 64 位系统上)的大小。每个 heapArena 都有自己独立的管理数据结构,用于跟踪和管理该 heapArena 中的内存分配情况

  • mheap: 堆内存的抽象,把从 OS 申请出的内存页组织成 Span,并保存起来

    mheap将span组织为树结构,按照page数量进行排序

    • free: 保存的 span 是空闲并且非垃圾回收的 span
    • scav: 保存的是空闲并且已经垃圾回收的 span

在这里插入图片描述

此外,内存管理还存在大小概念,用于更好地分配合适的内存块

  • objectSize: 申请内存的实际大小

  • size class: 表示 size 的级别,相当于把 size 归类到一定大小的区间段,比如 size[1,8] 属于 size class 1size(8,16] 属于 size class 2

  • span class: 与size class对应,表示特定大小的span类别,并且还有有指针和无指针两个版本(无指针不需要gc扫描)

    共有0-133级别,每个级别都有nonempty和empty span链表。

    • nonempty 保证所有 span 都至少有 1 个空闲的对象空间。这些 span 是 mcache 释放 span 时加入到该链表的
    • empty 所有的 span 都不确定里面是否有空闲的对象空间。当一个 span 交给 mcache 的时候,就会加入到 empty 链表

分配过程

Go按照不同对象大小有不同的分配逻辑

微对象(0, 16B)

mcache中的微分配器进行分配的

在mcache结构体中有如下字段

  • tiny uintptr: 指向当前微小块(tiny block)的起始位置,或者如果当前没有微小块则为 nil.

    用于跟踪分配给微小对象的内存块

  • tinyoffset uintptr: 表示当前微小块的偏移量,用于指示在当前微小块中已使用的内存位置

  • tinyAllocs uintptr:记录由拥有这个 mcache 的 P(Processor)执行的微小分配次数

微分配器将多个微小块分配请求合并到同一个内存块中,只有当内存块中的所有对象都需要被回收时,整片内存才可能被回收。

微分配器管理的对象不可以是指针类型,管理多个对象的内存块大小可以通过变量 maxTinySize 调整,在默认情况下,内存块的大小为 16 字节

小对象[16B, 32KB]

根据span class映射表寻找span,分配对象空间

  1. 计算对象所需内存大小size
  2. 映射size到size class
  3. 根据size class和对象是否包含指针计算出span class
  4. 获取该span class指向的span

在具体申请span上

  • 会首先向mcache中申请,不行则向mcentral申请
  • mcentral会先从non empty搜索满足条件的span,然后再从empty进行寻找
  • 在mcentral也找不到的情况下,就向mheap申请span
  • mheap会优先从free搜索可用的span,然后再从scav寻找
  • 最后还是找不到,就只能向OS申请内存了

大对象(32KB以上)

直接runtime.largeAlloc分配大块内存

Ref

  1. https://medium.com/safetycultureengineering/an-overview-of-memory-management-in-go-9a72ec7c76a8
  2. https://draveness.me/golang/docs/part3-runtime/ch07-memory/golang-memory-allocator/
  3. https://xiaoming.net.cn/2020/12/16/Go%20%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86%E4%B8%8E%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6/

网站公告

今日签到

点亮在社区的每一天
去签到