【go】内存分配模型

2024-09-07 23:36
文章标签 go 内存 分配 模型

本文主要是介绍【go】内存分配模型,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

内存是怎么分配给对象的?
内存分配优化的地方是?
讲讲golang内存分配模型?

ans:
1.按照对象的大小分配:先算出对象的大小如果是tiny对象,就从tiny block中获取地址和偏移量,将对象打包到mcache;如果是16B以上32k以内就先从mcache获得对应class级别的span;如果mcache没有就从mcenter中获取,如果mcenter没有就创建一个mspan从free树或scav树中获得内存页。如果堆中没有就系统调用申请内存,后再扫描树。
2.优化的地方是使用了类似于tcmalloc模型,向每个p预分配2k的缓存减少系统分配的次数且mcahe是p私有的不用加锁操作;
3.将page组织进span作为内存管理的基本单位;mcache中根据page的页数范围不同class的span链表;mcenter作为缓存池存放不同class的两个span链表,一个链表叫empty不确定里面是否有空闲的对象空间,另一个是noempty所有span都至少有1个空闲的对象空间.mheap存放两个二查排序空闲已回收树,free树:空闲未垃圾回收。scav树:空闲已垃圾回收。

面对三连问,你是不是和我一样懵逼了?以下是我查询资料学习总结的知识体系,一起看下去吧🙀

1.存储的基本知识

计算机存储体系:
[图片]

cpu的运算速度很快,而其他的硬件速度慢,为了好好利用cpu的性能所以加入了高速缓存和层层缓存层。
引入虚拟缓存后,操作系统向进程屏蔽了物理物理,cpu查询内存如果高速cache没有命中就会查找页表从磁盘将物理内存加载进缓存更新页表映射。由于引入虚拟内存所以物理内存的并发访问问题的级别由进程级转为了多线程级别。

2.TCMalloc

2.1基础

学习内存先得了解两个内存区域:
栈内存:栈中的内存会自动回收,内存管理简单,分配快。
堆内存:堆上的内存需要手动分配和释放,浪费gc。
堆内存管理分为三个重要步骤:
分配内存、(使用内存)、回收内存、组织内存块
一个内存块中包含了:元数据、用户数据、对齐字段
分配:从堆中把内存分配出来,将信息存进内存块,将内存块组织为链表。
释放:从链表中的内存块取出标记为未使用。
分配顺序:从链表中获得未使用的内存块没有再从内存中分配。

2.2tcmalloc机制

引入TCmalloc
同一进程所有线程共享空间,为了更快的分配内存,为每个线程预分配一些内存,再申请小内存可以直接从缓存分配。因为只有一次系统调用且分配无需加锁,因此,可以达到快速分配的目的。
[图片]

内存管理的基本单位是page,一组连续的page被称为span,tcCache是线程级别的缓存,包含有不同级别的span链表,centralCache是所有线程共享的缓存包含不同级别的span只是访问需要加锁,pageHeap是堆内存的抽象保存若干span链表和large span set保存中大对象.
小对象的分配流程:ThreadCache -> CentralCache -> HeapPage,大部分时候,ThreadCache缓存都是足够的,不需要去访问CentralCache和HeapPage,无锁分配加无系统调用,分配效率是非常高的。
中对象分配流程:直接在PageHeap中选择适当的大小即可,128 Page的Span所保存的最大内存就是1MB。
大对象分配流程:从large span set选择合适数量的页面组成span,用来存储数据。

3.Go的内存管理与分配

[图片]

不同级别的内存管理对象:
page:8kb
span:内存管理的基本单位
mcahe:线程级别的缓存,无锁访问,mcache与p绑定
mcentral:线程共享的缓存,加锁访问,每个级别的span有有指针的链表和无指针的链表
mheap:从操作系统中分配的内存页按照span组织起来,组织形式是二叉排序树:
free树:空闲并未垃圾回收
scav:空闲已经垃圾回收
[图片]

小对象是在mcache中分配的,而大对象是直接从mheap分配的,从小对象的内存分配看起。
不同大小的对象内存分配:
小对象:

  1. 计算对象所需内存size
  2. Size class和是否需要指针获得span class
  3. 获取对应class级别的cspan
    a.mcache ->b. mcenteal ->c.mheap
    span内的所有内存块都被占用时,没有剩余空间继续分配对象,mcache会向mcentral申请1个span,mcache拿到span后继续分配对象。
    mcentral有两个链表。
  • nonempty:这个链表里的span,所有span都至少有1个空闲的对象空间。这些span是mcache释放span时加入到该链表的。
  • empty:这个链表里的span,所有的span都不确定里面是否有空闲的对象空间。当一个span交给mcache的时候,就会加入到empty链表。
    mcentral会先从nonempty搜索满足条件的span,如果没有找到再从emtpy搜索满足条件的span,然后把找到的span交给mcache。
    mcentral需要向mheap提供需要的内存页数和span class级别,然后它优先从free中搜索可用的span,如果没有找到,会从scav中搜索可用的span,如果还没有找到,它会向OS申请内存,再重新搜索2棵树,必然能找到span。如果找到的span比需求的span大,则把span进行分割成2个span,其中1个刚好是需求大小,把剩下的span再加入到free中去,然后设置需求span的基本信息,然后交给mcentral。
    大对象:
    99%的流程与mcentral向mheap申请内存的相同
    栈内存:每个goroutine都有自己的栈,栈的初始大小是2KB,100万的goroutine会占用2G,但goroutine的栈会在2KB不够用时自动扩容,当扩容为4KB的时候,百万goroutine会占用4GB。在rpc调用(grpc invoke)时,栈会发生扩容(runtime.morestack),也就意味着在读写routine内的任何rpc调用都会导致栈扩容, 占用的内存空间会扩大为原来的两倍,4kB的栈会变为8kB,100w的连接的内存占用会从8G扩大为16G(全双工,不考虑其他开销)
  1. 根据分配对象的大小,选用不同的结构做分配。包括 3 种情况:
    1. 小于 16B 的用 mcache 中的 tiny 分配器分配;
    2. 大于 32KB 的对象直接使用堆区分配;
    3. 16B 和 32KB 之间的对象用 mspan 分配。
  2. 现在我们假定分配对象大小在 16B 和 32KB 之间。在 mcache 中找到合适的 mspan 结构,如果找到了就直接用它给对象分配内存。
  3. 我们这里假定此时没有在 mcache 中找到合适的 mspan。需要到 mcentral 结构中查找到一个 mspan 结构并返回。虽然 mcentral 结构对 mspan 的大小和是否空闲进行了分类管理,但是它对所有的 P 都是共享的,所以每个 P 访问 mcentral 结构都要加锁。
  4. 假定 Go 运行时在进行了一些扫描回收操作之后,在 mcentral 结构还是没有找到合适的 mspan。Go 运行时就会建立一个新的 mspan,并找到 heapArea 分配相应的页面,把页面地址和数量写入 mspan 中。然后,把 mspan 插入 mcentral 结构中,返回的同时将 mspan 插入 mcache 中。最后用这个新的 mspan 分配对象,返回对象地址。
    微小对象分配:
    从tiny block中分配,这些对象被打包到线程本地缓存(mcache)中,在同一个内存块中存储多个 tiny 对象,从而减少碎片化和全局锁的争用。

这篇关于【go】内存分配模型的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1146487

相关文章

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

NameNode内存生产配置

Hadoop2.x 系列,配置 NameNode 内存 NameNode 内存默认 2000m ,如果服务器内存 4G , NameNode 内存可以配置 3g 。在 hadoop-env.sh 文件中配置如下。 HADOOP_NAMENODE_OPTS=-Xmx3072m Hadoop3.x 系列,配置 Nam

Andrej Karpathy最新采访:认知核心模型10亿参数就够了,AI会打破教育不公的僵局

夕小瑶科技说 原创  作者 | 海野 AI圈子的红人,AI大神Andrej Karpathy,曾是OpenAI联合创始人之一,特斯拉AI总监。上一次的动态是官宣创办一家名为 Eureka Labs 的人工智能+教育公司 ,宣布将长期致力于AI原生教育。 近日,Andrej Karpathy接受了No Priors(投资博客)的采访,与硅谷知名投资人 Sara Guo 和 Elad G

Retrieval-based-Voice-Conversion-WebUI模型构建指南

一、模型介绍 Retrieval-based-Voice-Conversion-WebUI(简称 RVC)模型是一个基于 VITS(Variational Inference with adversarial learning for end-to-end Text-to-Speech)的简单易用的语音转换框架。 具有以下特点 简单易用:RVC 模型通过简单易用的网页界面,使得用户无需深入了

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验

图神经网络模型介绍(1)

我们将图神经网络分为基于谱域的模型和基于空域的模型,并按照发展顺序详解每个类别中的重要模型。 1.1基于谱域的图神经网络         谱域上的图卷积在图学习迈向深度学习的发展历程中起到了关键的作用。本节主要介绍三个具有代表性的谱域图神经网络:谱图卷积网络、切比雪夫网络和图卷积网络。 (1)谱图卷积网络 卷积定理:函数卷积的傅里叶变换是函数傅里叶变换的乘积,即F{f*g}

秋招最新大模型算法面试,熬夜都要肝完它

💥大家在面试大模型LLM这个板块的时候,不知道面试完会不会复盘、总结,做笔记的习惯,这份大模型算法岗面试八股笔记也帮助不少人拿到过offer ✨对于面试大模型算法工程师会有一定的帮助,都附有完整答案,熬夜也要看完,祝大家一臂之力 这份《大模型算法工程师面试题》已经上传CSDN,还有完整版的大模型 AI 学习资料,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

AI Toolkit + H100 GPU,一小时内微调最新热门文生图模型 FLUX

上个月,FLUX 席卷了互联网,这并非没有原因。他们声称优于 DALLE 3、Ideogram 和 Stable Diffusion 3 等模型,而这一点已被证明是有依据的。随着越来越多的流行图像生成工具(如 Stable Diffusion Web UI Forge 和 ComyUI)开始支持这些模型,FLUX 在 Stable Diffusion 领域的扩展将会持续下去。 自 FLU

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者