Golang内存分配


Go内存分配语雀笔记整理

    • Golang内存模型设计理念思考
    • 核心代码阅读
      • mspan
      • mcache
      • mcentral中心缓存
      • mheap
      • 分配过程

Golang内存模型设计理念思考

golang内存分配基于TCmalloc模型,它核心在于:空间换时间,一次缓存,多次复用;
为何要有这种缓存机制?如果golang每次分配内存都向操作系统申请,需要切换到内核态发起系统调用,(权级切换时的开销是很大的)代价太高;所以一次缓存,多次复用(类似GMP的设计思想尽可能不切到内核态)

堆mheap这种数据结构就是一次缓存得到的那部分。 在操作系统视角中,mheap就是用户进程缓存的内存,在golang视角中,mheap就是内存的源头
mheap作为进程中的内存来源,全局唯一,具有全局锁,如果mheap直接分配,那么存取性能是非常可怕的,为了提高分配效率,就要实现锁的粒度更细、甚至无锁,goalng借鉴操作系统的多级缓存模型(L1,L2,L3,RAM,磁盘),设计了一种3层缓存模型:mheap、 mcentral、 mchace(GMP中的P相当于一个CPU,而mache就是P本地私有的内存,它冗余了各种等级的mspan,P本地私有不涉及并发行为,所以不需要加锁);

image.png

核心代码阅读

mspan

mspan是最小的内存管理单元,它跟golang设定的对象等级制度紧密关联;mspan结构体的核心字段:相同等级的mspan构成一条双向链表,所以mspan有前后指针; mspan管理整数倍的连续地址的页,所以有管理的内存起始地址,以及连续的页数; mspan的等级意味着它管理的块的大小,所以有一个标志等级的变量(1~67、以及0级处理大对象,等级用unit8来表示,高7位标识等级,最低位标识noscan信息,noscan用于标记当前mspan的内存需不需要在GC的时候进一步扫描,如果对象不包含指针,说明对象没有引用其他对象,那么垃圾回收的时候就不需要进一步扫描了。这样可以提高扫描效率); 分配内存时分配的其实是对应的槽位,所以有一个位图用来记录槽位,比如要分配31B的obj,那么就会向上到等级为32的mspan中根据它的位图找空闲的槽位(这是内部碎片的来源)。这个位图bitmap在后续的垃圾回收中也会使用到。 它的快速查找空闲槽用到了CTZ64算法
image.pngimage.png
image.png

mspan详解:既然相同size class的mspan节点聚集构成一条双向链表,所以mspan节点有next,pre指针,另外一个mspan管理的内存大小从startaddr开始,往后npages个page。当要分配obj的时候,会去alloccache记录的bitmap中去找为1的obj。 alloccache记录的bitmap就是记录obj的槽位
image.png
image.png

源码中核心的点: next、pre指针; startaddr; npages;alloccache(bitmap);spanclass(等级);freeindex(记录bitmap在某位之前的obj都被占用过了,加速找bitmap中Obj为1的槽位)
另外spanclass 是一个uint8 整数,高7位标识1~67+隐藏0级(处理更大对象) 共68个等级,最低位标识noscan信息。noscan标志是用来标记垃圾回收的时候需不需要扫描的标志位。
如果对象不包含指针,说明对象没有引用其他对象,那么垃圾回收的时候就不需要进一步扫描了。这样可以提高扫描效率

mcache

mcache是P的本地私有内存,在单个P内部是没有并发的,所以没有锁; 核心字段: alloc, mcache冗余了一些mspan,具体来说的话是两种,一种noscan类型的无需重复扫描,一种scan类型的。 另外mcache结构体中还有微型对象分配器(<16B)tinyalloc。
image.png
image.png

mcentral中心缓存

mcentral是相同等级mspan构成的两条链表,一条有空间,一条满空间,每个mcentral有一把锁,但是锁的粒度相比mheap更细;所以核心字段的话就是两条链表,一把锁,一个等级;

image.png
image.png

mheap

进程内全局唯一,访问加全局锁(因此对mheap的存取性能是非常可怕的),对于go上层来说mheap是操作系统虚拟内存的抽象,是go进程内部的内存之源,由于向操作系统申请内存这个操作很重,所以mheap一般一次申请比较大(64M)
mheap以8KB的页为最小内存单元,负责将连续的页组装成mspan,使用位图bitmap记录所有页的使用情况,为1说明页已经被mspan组装(不是被使用,组装了不一定使用了)(组装的时候找连续空闲页时为了加速,使用到了空闲页基数树索引辅助) 用heapArena聚合页记录页跟mspan的映射关系(GC的时候根据对象地址找到页是很简单的,但是mspan的记录对象使用情况的bitmap也需要更新,所以需要heapArena记录页跟mspan的映射关系,用来更新mspan的bitmap)。

分配过程

tiny微对象(<16B )的话,走mcache的微型分配器;
(<32KB的对象)优先从mcache中找对应等级mspan中的空槽(无锁),如果mcache兜不住就向上去mcentral;
根据等级去mcentral中的有空闲链表中找到mspan填充mcache(有锁),如果兜不住,继续向上去mheap;
mheap组装mspan填充到mcentral,然后从mspan中取内存(有锁),如果还兜不住,说明进程中没有足够的内存了,此时mheap会向操作系统申请内存(以heapArena为单位64MB);
0级别的大对象(>32KB),直接到mheap中

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/763472.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于x86+FPGA+AI轴承缺陷视觉检测系统,摇枕弹簧智能检测系统

一、承缺陷视觉检测系统 应用场景 轴类零件自动检测设备&#xff0c;集光、机、软件、硬件&#xff0c;智能图像处理等先进技术于一体&#xff0c;利用轮廓特征匹配&#xff0c;目标与定位&#xff0c;区域选取&#xff0c;边缘提取&#xff0c;模糊运算等算法实现人工智能高…

Linux 高级编程——线程控制

线程控制&#xff1a;互斥与同步 概念&#xff1a; 互斥 》在多线程中对临界资源的排他性访问。 互斥机制 》互斥锁 》保证临界资源的 访问控制。 pthread_mutex_t mutex; 互斥锁类型 互斥锁变量 内核对象 框架&#xff1a; 定义互斥锁 》初始化锁 》加…

Kafka-服务端-副本同步-源码流程

杂 在0.9.0.0之前&#xff0c;Kafka提供了replica lag.max.messages 来控制follower副本最多落后leader副本的消息数量&#xff0c;follower 相对于leader 落后当超过这个数量的时候就判定该follower是失效的&#xff0c;就会踢出ISR&#xff0c;这里的指的是具体的LEO值。 对…

Hadoop权威指南-读书笔记-01-初识Hadoop

Hadoop权威指南-读书笔记 记录一下读这本书的时候觉得有意思或者重要的点~ 第一章—初识Hadoop Tips&#xff1a; 这个引例很有哲理嘻嘻&#x1f604;&#xff0c;道出了分布式的灵魂。 1.1 数据&#xff01;数据&#xff01; 这一小节主要介绍了进入大数据时代&#xff0c;面…

【windows|012】光猫、路由器、交换机详解

&#x1f341;博主简介&#xff1a; &#x1f3c5;云计算领域优质创作者 &#x1f3c5;2022年CSDN新星计划python赛道第一名 &#x1f3c5;2022年CSDN原力计划优质作者 ​ &#x1f3c5;阿里云ACE认证高级工程师 ​ &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社…

QML学习——Qt Quick Extras Examples 1.4(八)

Qt Quick Extras Examples 阅读官方的源码然后尝试做了下 01 A car dashboard 样例演示&#xff1a; 说明&#xff1a; ValueSource组件控制数值相关的动画&#xff0c;例如图中数值的变化&#xff1b;TurnIndicator组件是控制左右方向灯的闪烁和背景&#xff0c;里面使用…

excel修改批量一列单价的金额并保留1位小数

1.打开表格&#xff0c;要把单价金额变成现在的两倍&#xff0c;数据如下&#xff1a; 2.把单价这一列粘贴到一个新的sheet页面&#xff0c;在B2单元格输入公式&#xff1a;A2*2 然后按enter回车键,这时候吧鼠标放到B2单元格右下角&#xff0c;会出现一个黑色的小加号&#xf…

SQL 注入联合查询之为什么要 and 1=2

在 SQL 注入联合查询中&#xff0c;将 id 先置为假&#xff08;如 id-1 或其他使查询结果为空的条件&#xff09;&#xff0c;通常是为了让前面的查询语句查询不到结果&#xff0c;从而使联合查询中后面的语句结果能够显示在回显位上

【深度学习】pytorch训练中的一个大坑

使用的命令&#xff1a;iostat -x 5 可以看到 ssd的利用率已经满了。 之前在的数据集放在了 hdd上&#xff0c;训练结果特别慢。 所以我把它移动到了ssd上&#xff0c;然后训练参数用的 resume&#xff0c; 但是&#xff01;&#xff01;&#xff01;&#xff01;它把历史记住…

虚拟环境管理

虚拟环境 在使用 Python 时我们一般使用“pip install 第三方包名”来安装第三方包&#xff0c;但是由于pip的特性&#xff0c;系统只能安装每个包的一个版本。而在实际开发中&#xff0c;可能同时开发多个项目&#xff0c;如&#xff1a;上图有三个项目&#xff1b;每个项目需…

摄影后期色彩管理流程(Lightroom篇)

在摄影后期处理中&#xff0c;色彩管理是确保图像从捕捉到输出的一致性和准确性的关键。Lightroom 和 Photoshop 其实已经将这套色彩管理流程作为默认选项&#xff0c;如果实质操作时仍存在色彩偏差的问题&#xff0c;可参考以下内容。 ProPhoto RGB > Adobe RGB > sRGB …

幻兽帕鲁服务器如何安装模组安装

由于模组多数为Window版本的&#xff0c;所以本教程以服务端为Window的作为演示&#xff08;Linux服务端的也是一样的操作&#xff09;百度莱卡云开服 如果你你是Linux版本的&#xff0c;请点击跳转切换服务端教程 接下来是本地安装模组包的方法&#xff08;服务器自带&#xf…

Web3 游戏周报(6.23 - 6.29)

区块链游戏热度不减&#xff0c;你是否掌握了上周的重要动态&#xff1f; 回顾上周区块链游戏动态&#xff0c;查看 Footprint Analytics 与 ABGA 的最新数据报告。 【6.23 - 6.29】Web3 游戏行业动态&#xff1a; 继 Notcoin 之后&#xff0c;另一款 Telegram 游戏 Hamster …

React实战学习(一)_棋盘设计

需求&#xff1a; 左上侧&#xff1a;状态左下侧&#xff1a;棋盘&#xff0c;保证胜利就结束 和 下过来的不能在下右侧&#xff1a;“时光机”,保证可以回顾&#xff0c;索引 语法&#xff1a; 父子之间属性传递&#xff08;props&#xff09;子父组件传递&#xff08;写法上&…

【MySQL篇】Percona XtraBackup物理备份工具的基础理论概述(第一篇,总共五篇)

&#x1f4ab;《博主介绍》&#xff1a;✨又是一天没白过&#xff0c;我是奈斯&#xff0c;DBA一名✨ &#x1f4ab;《擅长领域》&#xff1a;✌️擅长Oracle、MySQL、SQLserver、阿里云AnalyticDB for MySQL(分布式数据仓库)、Linux&#xff0c;也在扩展大数据方向的知识面✌️…

​产品经理-困惑4:产品面对开发是否低人一等(4)

在互联网当中,做产品的,在面对开发是否觉得低人一等&#xff1f; 完全不会 从团队层面来看&#xff0c;任何互联网团队都是由开发、产品、视觉、运营、市场等专业人才所组成的专业团队 每人各有专攻&#xff0c;为同一个目标&#xff08;即项目成功&#xff09;而不懈努力。各工…

带安全启动—Ubuntu系统—手动安装Nvidia驱动

教程1&#xff1a;在启用安全启动的 Fedora 中安装英伟达驱动 教程2&#xff1a;UEFI安全启动模式下安装Ubuntu的NVIDIA显卡驱动 1. 搜索合适的驱动 Nvidia驱动官网 选择这个 驱动(.run)链接 2. 安装必要的软件依赖 CUDA底层用C写的&#xff0c;因此导入编译器 sudo apt i…

1-4.时间序列数据建模流程范例

文章最前&#xff1a; 我是Octopus&#xff0c;这个名字来源于我的中文名–章鱼&#xff1b;我热爱编程、热爱算法、热爱开源。所有源码在我的个人github &#xff1b;这博客是记录我学习的点点滴滴&#xff0c;如果您对 Python、Java、AI、算法有兴趣&#xff0c;可以关注我的…

已解决java.io.NotSerializableException:对象不支持序列化的正确解决方法,亲测有效!!!

已解决java.io.NotSerializableException&#xff1a;对象不支持序列化的正确解决方法&#xff0c;亲测有效&#xff01;&#xff01;&#xff01; 目录 问题分析 出现问题的场景 示例代码 报错原因 解决思路 解决方法 1. 实现Serializable接口 修改后的Employee类 2…

递归----计算P函数

注意运算中的符号不能少&#xff01;&#xff01;&#xff01;&#xff01; * 必须体现出&#xff01;&#xff01;&#xff01;&#xff01; #include <stdio.h>double P( int n, double x );int main() {int n;double x;scanf("%d %lf", &n, &x);pri…