欢迎光临散文网 会员登陆 & 注册

go内存管理-内存分配-学习心得

2023-01-01 15:46 作者:风格星辰  | 我要投稿

今天想分享下自己学习go内存分配的一些心得。

首先,go程序启动时需要向系统申请内存资源。内容包含三个部分

spans:指针,指向arena的指针

bitmap:垃圾回收使用

arena:真正的存储空间

这个概念大概了解即可。

go的内存管理采用的是分级管理从cache->central->heap并且采用分类分配,将对象分为0-66共67类。

通过内存管理单位mspan来进行管理,将内存分页,每页8K。

每个协程有自己的cache,当cache不够用的时候向cental申请,central不够向heap申请,heap不够向内存申请。

mcache里持有67*2个类型的mspan。每个类型的分两种。一种是需要扫描的即带指针的,一种是不需要扫描即不带指针的。主要是为了垃圾回收方便。

mheap持有67*2个类型的mcentral。每个类型也分两种。一个是需要扫描的,一种是不需要扫描的。

当某个类型的mspan不够用了,就向对应类型的mcentral申请资源。

mcentral有两个链表,一个是empty已经申请的空间,一个是noempty空闲的可以申请的空间。

申请时需要加锁,因为是全局资源,避免竞争。然后mcentral将从noempty中分配mspan,将其加入到empty中。返回并解锁。

回收的时候也一样,先加锁。然后将内存从empty中删除,加入到noempty中,然后解锁。

基本就是这么一个过程了。

分配的时候,如果小于16B并且不包含指针,使用tiny分配。16B到32K的正常分配。大于32K的有mheap分配。

以申请size为n的内存为例,分配步骤如下:

  1. 获取当前线程的私有缓存mcache

  2. 跟据size计算出适合的class的ID

  3. 从mcache的alloc[class]链表中查询可用的span

  4. 如果mcache没有可用的span则从mcentral申请一个新的span加入mcache中

  5. 如果mcentral中也没有可用的span则从mheap中申请一个新的span加入mcentral

  6. 从该span中获取到空闲对象地址并返回

欢迎和谐讨论

参考自go专家编程

第四章:内存管理 - 4.1 内存分配原理 - 《GO专家编程》 - 书栈网 · BookStack


go内存管理-内存分配-学习心得的评论 (共 条)

分享到微博请遵守国家法律