Go內存分配

圖解Go語言內存分配 - 知乎

go內置運行時,采用了自主管理,實現更好的內存使用模式,不需要每次內存分配都進行系統調用

采用TCMalloc算法:把內存分為多級管理,從而降低鎖的粒度

將可用的堆內存采用二級分配的方式進行管理:

每個線程都會自行維護一個獨立的內存池,內存分配時優先從內存池中分配,內存池不足時向全局內存池申請,避免對全局內存池的頻繁競爭

在程序啟動時,向操作系統申請一塊內存
請添加圖片描述
arena:堆區,go動態分配內存,把內存分割為8kb大小的頁,一些頁組合稱為mspan

bitmap:標識 arena 中哪些地址保存了對象,并用4bit標志位標識對象是否包含指針,GC標記信息

? 1個byte大小內存對應 arena區域中4個指針大小(指針大小8B)內存
bitmap的高地址指向arena的低地址,bitmap由高地址向低地址增長
請添加圖片描述
span:存放mspan(arena 分割的頁組合起來的內存管理基本單元)的指針,每個指針對應一頁

? 創建mspan時,按頁填充對應的spans區域

內存管理單元

mspan:內存管理的基本單元,由一片連續的8kb的頁組成的大塊內存,一般是操作系統頁大小的幾倍,包含起始地址、mspan規格、頁的數量等內容的雙端鏈表

每個mspan按照自身的屬性Size Class大小分割為若干個object,每個object存儲一個對象

并且使用一個位圖標記未使用的object

屬性Size Class決定object大小,mspan只會分配給object尺寸大小接近的對象,對象大小小于object

每個Size Class兩個mspan(span class)一個分配給含有指針的對象,一個分配個不含有指針對象
請添加圖片描述

操作系統存儲模型

多級模型 動態切換(因為數據的調用頻率在實時發生變化)
請添加圖片描述

虛擬內存與物理內存

在真實物理內存上的虛擬概念,用來代理,貼合用戶使用視角

使用戶(進程)覺得內存是連續的,而不是割裂的

實現內存“放大”的效果,虛擬內存可以由物理內存+磁盤補足,根據數據冷熱進行動態置換

通過頁表建立真實物理空間的映射關系

頁表:聚合映射關系的數據結構
請添加圖片描述

分頁管理

虛擬內存中最小的操作單元:頁

物理內存:幀

提高內存空間利用率(以頁為粒度,外部碎片被替換為內部碎片,更相對可控)

提高內外交換效率

與虛擬內存機制呼應,建立虛擬地址到物理地址的映射關系

Golang內存模型

以空間換時間,一次緩存,多次復用

每次向操作系統多申請內存

堆mheap同樣的思想:

對操作系統,用戶進程中緩存的內存

對Go進程內部,堆是所有對象的內存起源

多級緩存,實現無/細鎖化
請添加圖片描述
mcentral 根據對象的大小從小到大排列等級(集合)

當分配內存給一個對象時,會根據其大小找到從屬的等級,在對應的mcentral中嘗試獲取內存

mcache 每個處理器§單獨的本地私有緩存,其中冗余每一種等級的內存空間

當嘗試獲取內存時,根據處理器,查看本地私有的mcache中是否有合適的空間使用,有則直接獲取,無則訪問mcentral,一級一級升級向上獲取

多級規格,提高利用率
mcentral
請添加圖片描述
page:go中有獨立的內存存儲單元,最小的存儲單元 8KB

mspan:最小的管理單元,為page的整數倍,從8B到80KB分為67種不同的規格,分配對象時根據大小映射到不同規格的mspan,獲取空間

隱藏的0級,處理更大的對象,上不封頂
請添加圖片描述

mspan

屬于mcentral的一個節點,根據span的不同等級有一個central實例,central存儲的span個數是復數
請添加圖片描述
stratAddr 起始地址 映射到Go語言中堆內存的一部分空間,也是虛擬內存中對應的地址

npages 頁的頁數,每個mspan中的頁是連續的,可以根據起始地址+頁數推導出,對應的內存區域
請添加圖片描述
allocCache 基于bitmap輔助快速找到空閑內存塊(塊大小為對應等級下對象大小)

查找mspan中哪些頁是空閑的,可以把對象分配到里面
請添加圖片描述

type mspan struct {_    sys.NotInHeap// 標識前后節點的指針next *mspan     prev *mspan     // 起始地址startAddr uintptr// 包含頁數,頁是連續的npages    uintptr // 標識此前的位置(bit位)都已被占用freeindex uint16// 最多可存放多少個對象(會出現一頁存放多個對象的情況)nelems uint16// 每個bit對應一個對象塊,標識該塊是否被占用allocCache uint64// 標識mspan等級,包含class和noscan信息spanclass spanClass......
}

請添加圖片描述
bytes/obj:該大小規格的對象會從當前等級的mspan中獲取空間,創建對象過程中,大小會向上取整為8B的整數倍,可以直接實現對象到mspan等級映射

bytes/span:該等級的mspan的總空間大小

object:最多可以new多少個對象

max waste:
請添加圖片描述
請添加圖片描述

// nocan 標識對象是否包含指針,在gc時是否需要展開標記
// 存在指針需要展開掃描形成完整的有向圖
// 會將兩類對象,劃分給不同的span(同一等級下的不同span)
// 將class+nocan組裝為uint8,形成完整的spanClass 標識
// 高7位表示span等級,最低為表示nocan信息
type spanClass uint8func makeSpanClass(sizeclass uint8, noscan bool) spanClass {return spanClass(sizeclass<<1) | spanClass(bool2int(noscan))
}func (sc spanClass) sizeclass() int8 {return int8(sc >> 1)
}func (sc spanClass) noscan() bool {return sc&1 != 0
}

mcache

每個P獨有的緩存,交互無鎖
請添加圖片描述
alloc 將每種spanClass等級的mspan各緩存一個,總數為2*68

對象分配器 tiny allocator 處理小于16B對象的內存分配

type mcache struct {_ sys.NotInHeap// 微對象分配器相關tiny       uintptrtinyoffset uintptrtinyAllocs uintptr// mcache中緩存的mspan,每種各一個alloc [numSpanClasses]*mspan ......
}

mcentral中心緩存

請添加圖片描述
每個central對應一個spanClass

會將mspan分為兩個鏈表,有空間mspan鏈表partial和滿空間mspan鏈表 full

type mcentral struct {_         sys.NotInHeap// 對應的spanClassspanclass spanClass// 有空位mspan集合// 數組長度為2,抗一輪GCpartial [2]spanSet // 無空位full    [2]spanSet
}

mheap全局堆緩存

對于Golang上層應用,堆是操作系統虛擬內存的抽象

堆內存中最小內存存儲單元:頁(8KB)

負責將連續頁組裝為mspan

全局內存基于bitMap標識使用情況,一個bit對應一頁,0自由,1已被組裝為mspan

通過heapArena聚合頁,記錄頁到mspan的映射信息,維護頁所屬的mspan關系

建立空閑頁基數樹索引 radix tree index 快速尋找空閑頁,獲取至少在虛擬視角下連續的空閑頁

mcentral 的持有者,持有所有spanClass下mcentral,作為自身緩存,mcentral是mheap更細粒度的緩存(以空間換時間的操作)

內存不夠,向操作系統申請,單位:heapArena(64M)

type mheap struct {_ sys.NotInHeap// 堆的全局鎖(進程維度)lock mutex// 空閑頁分配器,底層由多棵基數樹組成的索引,每棵樹對應16GB內存空間pages pageAlloc // 記錄所有mspan// 所有mspan都是由mheap,使用連續空閑頁組裝allspans []*mspan // heapAreana 數組 請求內存和映射關系// 64位系統下,二維數組容量為[1][2^22]// 每個heapArena大小64M// 理論上堆的上限為 2^22*64M = 256Tarenas [1 << arenaL1Bits]*[1 << arenaL2Bits]*heapArena// 多個mcentral,總數為spanClass 個數central [numSpanClasses]struct {mcentral mcentral// 用于內存地址對齊pad      [(cpu.CacheLinePadSize - unsafe.Sizeof(mcentral{})%cpu.CacheLinePadSize) % cpu.CacheLinePadSize]byte}......
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/88959.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/88959.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/88959.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

cursor使用mcp連接mysql數據庫,url方式

背景。 用cursor生成后端代碼。讓cursor可以創建響應的表結構以及插入數據。使用的cursor版本是1.2.1 cursor 官網 mcp 說明smithery 中mysql mcp這個mcp具有建表的本領。 在cursor中是這樣配置的。 以上這種配置方式是是通過在smithery 網站中配置好自己的mysql數據庫連接后才…

Twisted study notes[1]

文章目錄serverreferencesserver Twisted usually using subclass twisted.internet.protocol.Protocol to treat protocols .Protocol is a fundamental class in Twisted for implementing network protocols.protocol class instant don’t exists forever because of it w…

Python 數據建模與分析項目實戰預備 Day 6 - 多模型對比與交叉驗證驗證策略

? 今日目標 引入多種常見分類模型&#xff08;隨機森林、支持向量機、K近鄰等&#xff09;比較不同模型的訓練效果使用交叉驗證提升評估穩定性&#x1f9fe; 一、對比模型列表模型類名&#xff08;sklearn&#xff09;適用說明邏輯回歸LogisticRegression基礎線、易于解釋KNNK…

xss-labs 1-8關

level1打開檢查&#xff0c;發現test直接放入h2標簽中此時通過script繞過h2標簽構造payload127.0.0.1/xss-labs/lvel1.php?name<script>alert(111)</script>直接使用script標簽繞過h2,并執行alert,通過level2打開檢查&#xff0c;輸入的123被放在input標簽里面的v…

Conda 核心命令快速查閱表

本表旨在提供一個簡潔、高效的 Conda 命令參考&#xff0c;專注于最常用功能的快速查找。 1. 環境管理 (Environment Management)功能 (Function)命令 (Command)示例 (Example)創建新環境conda create -n <env_name> [packages...]conda create -n myenv python3.9 panda…

音視頻學習(三十九):IDR幀和I幀

主要區分&#xff1a;I 幀 是幀內編碼幀&#xff0c;IDR 幀 是一種特殊的 I 幀&#xff0c;它是“清除參考幀鏈的強制切斷點”。H.264 視頻結構 結構 H.264 視頻由多個 NAL&#xff08;Network Abstraction Layer&#xff09;單元 構成&#xff0c;每一幀圖像可由一個或多個 NA…

人工智能與機器學習暑期科研項目招募(可發表論文)

人工智能與機器學習暑期科研項目招募 華中科技大學博士論文指導我是計算機專業的研二學生&#xff1a;從大二開始接觸科研&#xff0c;至今已發表1篇CCF-A類會議論文、1篇CCF-B類會議論文&#xff0c;以及2篇Top期刊論文。正是這段從本科開始的科研經歷&#xff0c;讓我在保研和…

C盤爆滿?一鍵清理恢復極速體驗!“小番茄C盤清理”徹底解放你的電腦

目錄 前言 C盤變紅&#xff1f;&#xff01;那么你的電腦將會出現下面糟糕的情況&#xff1a; 一、小番茄C盤清理介紹——拯救你的C盤爆紅&#xff01; 二、安裝登錄小番茄C盤清理 2.1 安裝小番茄C盤清理 2.2 登錄—擁有專屬自己電腦的小番茄C盤清理 三、手把手教你深度…

UI前端大數據可視化實戰技巧:如何利用數據故事化提升用戶參與度?

hello寶子們...我們是艾斯視覺擅長ui設計、前端開發、數字孿生、大數據、三維建模、三維動畫10年經驗!希望我的分享能幫助到您!如需幫助可以評論關注私信我們一起探討!致敬感謝感恩!一、引言&#xff1a;從 “圖表堆砌” 到 “故事共鳴” 的可視化革命當企業管理者面對布滿折線…

CSS基礎1.1

HTML骨架<!DOCTYPE html> <!-- 中文網站 --> <html lang"zh-CN"> <head><!--charset"UTF-8" 規定網頁的字符編碼 --><meta charset"UTF-8"><!-- ie(兼容性差) / edge --><meta http-equiv"X…

前端基礎JavaScript 筆記

本文是基于 B 站 pink 老師前端 JavaScript 課程整理的學習筆記 JS簡介 JavaScript是一種運行在客戶端&#xff08;瀏覽器&#xff09;的編程語言 作用&#xff1a;1.網頁特效(監聽用戶的一些行為讓網頁作出對應的反饋) 2.表單驗證(針對表單數據的合法性進行判斷) 3.數據交互…

「小程序開發」項目結構和頁面組成

微信小程序目錄 微信小程序的目錄,每種文件都有特定用途,組合起來才能構建完整應用。 小程序最基本的目錄結構通常包含這些部分: my-miniprogram/ ├── pages/ // 存放所有頁面 │ ├── index/ // 存放index頁面的邏輯文件 │ └── logs/ …

[element-ui]el-table在可視區域底部固定一個橫向滾動條

背景當el-table的列太多時&#xff0c;得拖動橫向滾動條才能看到&#xff0c;但如果內容也很多&#xff0c;可能橫向滾動條還看不到&#xff0c;又得滑到最下方才能拖動滾動條&#xff0c;這樣不太方便。若內容過多時&#xff0c;有個固定在可視區域的橫向滾動條就好了&#xf…

大模型核心組件結構與計算順序詳解(Embedding/FFN/LayerNorm等)

在大模型&#xff08;如GPT、BERT、LLaMA等&#xff09;的架構設計中&#xff0c;各個組件的協同工作是模型性能的核心保障。本文將詳細解析大模型中Embedding、前饋神經網絡&#xff08;FFN&#xff09;、LayerNorm、Softmax、MoE、殘差連接的作用及計算順序&#xff0c;幫助理…

希爾排序:突破傳統排序的邊界

一、算法思想希爾排序&#xff08;Shell Sort&#xff09;&#xff0c;也被叫做縮小增量排序&#xff0c;是插入排序的一種改進版本。希爾排序的核心在于先將整個待排序的記錄序列分割成若干個子序列&#xff0c;分別進行直接插入排序。隨著增量逐漸減小&#xff0c;子序列的長…

Kafka事務消息與Exactly-Once語義實戰指南

Kafka事務消息與Exactly-Once語義實戰指南 在分布式微服務或大數據處理場景中&#xff0c;消息隊列常被用于異步解耦、流量削峰和系統伸縮。對于重要業務消息&#xff0c;尤其是金融、訂單、庫存等場景&#xff0c;消息的精確投遞&#xff08;Exactly Once&#xff09;和事務一…

26.將 Python 列表拆分為多個小塊

將 Python 列表拆分為多個小塊(Chunk a List) ?? 場景 1:按份數 chunk_into_n(lst, n) 將一個列表平均拆分為 n 個塊。如果不能整除,最后一塊會包含剩余元素。 ? 示例代碼 from math import ceildef chunk_into_n(lst, n):size = ceil(len

18.理解 Python 中的切片賦值

1. 切片語法回顧 標準切片語法格式為: [start_at : stop_before : step]start_at:起始索引(包含)stop_before:結束索引(不包含)step:步長(默認為 1)例如: lst = [1, 2,

論文 視黃素與細胞修復

王偉教授發布&#xff0c;通過對比兔子和老鼠耳朵穿孔后的復原&#xff0c;控制變量法發現了 視黃素對細胞修復的影響

JavaScript 的執行上下文

當 JS 引擎處理一段腳本內容的時候,它是以怎樣的順序解析和執行的?腳本中的那些變量是何時被定義的?它們之間錯綜復雜的訪問關系又是怎樣創建和鏈接的?要解釋這些問題,就必須了解 JS 執行上下文的概念。 JavaScript引擎: JavaScript引擎是一個計算機程序,它接收JavaScri…