Golang的內(nèi)存管理--學(xué)習(xí)筆記
Go的內(nèi)存管理內(nèi)存的分級(jí)arena區(qū)SpansGo中的mspan內(nèi)存管理組件mcachemcentralmheap內(nèi)存的分配流程內(nèi)存的分級(jí)使用的是多級(jí)分配的辦法將內(nèi)存分為多級(jí)進(jìn)行分級(jí)管理從而降低鎖的粒度。并且將可用的堆內(nèi)存采用二級(jí)管理其中每個(gè)線程會(huì)有一個(gè)自己的內(nèi)存池只有在自己的內(nèi)存池不夠時(shí)才會(huì)去全局內(nèi)存中獲取夠用時(shí)首先使用自己的內(nèi)存池。基本概念arena區(qū)arena是堆區(qū)即動(dòng)態(tài)分配區(qū)域被分隔成8k大小的頁將頁組合起來稱為mspan。bitmap區(qū)域標(biāo)識(shí)arena區(qū)域的那些地址保存了對象并且使用4bit標(biāo)識(shí)對象是否包含指針、GC標(biāo)記信息。bitmap的的一個(gè)byte大小的內(nèi)存標(biāo)識(shí)的是arena的4個(gè)指針大小的內(nèi)存一個(gè)是8b因此bitmap的大小512GB/(4*8B)16GB。Spansspans中保存的是mspan是arena中分隔頁組成的基本內(nèi)存管理單元的指針每個(gè)指針對應(yīng)一頁會(huì)出現(xiàn)多個(gè)s指向同一個(gè)mspan每一個(gè)mspan中也保存了對應(yīng)的spans在回收時(shí)可以快速的找到Go中的mspanmspan是go內(nèi)存管理的基本單元是一片連續(xù)的8kb的頁組成的大塊內(nèi)存。mspan的特點(diǎn)mspan是包含頁的起始地址頁的span規(guī)格和頁的數(shù)量的雙端鏈表關(guān)于mspan和object的關(guān)系mspan是根據(jù)自身的SizeClass來分割成若干個(gè)object一個(gè)object可儲(chǔ)存一個(gè)對象在為對象分配內(nèi)存的時(shí)候mspan會(huì)分配一個(gè)和object大小接近的對象SizeClass和SpanClass的概念Size_Class Span_Class / 2由計(jì)算方式可以看出每一個(gè)Span_Class中有兩個(gè)mspan。一個(gè)分配給包含有指針的對象一個(gè)分配給不包含指針的對象。mspan和SizeClass在Go1.9中mspan的SizeClass有67種每個(gè)mspan分割的object大小是8*2n的倍數(shù)寫在代碼中// path: /usr/local/go/src/runtime/sizeclasses.go const _NumSizeClasses 67 var class_to_size [_NumSizeClasses]uint16{0, 8, 16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256, 288, 320, 352, 384, 416, 448, 480, 512, 576, 640, 704, 768, 896, 1024, 1152, 1280, 1408, 1536,1792, 2048, 2304, 2688, 3072, 3200, 3456, 4096, 4864, 5376, 6144, 6528, 6784, 6912, 8192, 9472, 9728, 10240, 10880, 12288, 13568, 14336, 16384, 18432, 19072, 20480, 21760, 24576, 27264, 28672, 32768}在使用SizeClass的時(shí)候其中為0表示大對象直接由對內(nèi)存分配小對象通過mspan來分配SizeClass也決定了mspan所能分配的頁數(shù)寫死在代碼中上圖中由兩個(gè)S指向同一個(gè)mspan這是因?yàn)閮蓚€(gè)s指向的P同屬一個(gè)mspan因此方便了互相查找。startAddr 直接指向了arena區(qū)域表示mspan的起始地址allocBIts指向一個(gè)位圖每位代表一個(gè)塊是否被分配了對象allocCount 表示已經(jīng)分配的對象個(gè)數(shù)內(nèi)存管理組件Go中的分配器的3中組件的構(gòu)成mcachemcentralmheapmcacheGo中為每個(gè)邏輯處理器P提供一個(gè)本地線程緩存即mcache每個(gè)P同一時(shí)間只能運(yùn)行一個(gè)goroutine因此訪問mcache是不需要加鎖mcache的結(jié)構(gòu)體定義//path: /usr/local/go/src/runtime/mcache.go type mcache struct { alloc [numSpanClasses]*mspan } numSpanClasses _NumSizeClasses 1mcache中使用numSpanClasses作為索引管理多個(gè)用于分配的mspan包含了所有規(guī)格的mspannumSpanClasses是mspan中介紹的_NumSizeClasses的2倍數(shù)組中的一半mspan是分配給有指針的對象一半是給沒有指針的對象。在垃圾回收的時(shí)候沒有指針的就不需要進(jìn)一步掃描了mcache的初始化在初始化時(shí)沒有mspan資源使用過程中動(dòng)態(tài)的從mcentral申請會(huì)緩存起來對象小于等于32k時(shí)使用mcashe中的mspan。mcentralmecntral為mcache提供切分好的mspan資源每個(gè)mcentral保存一種特定大小的全局mspan列表分配的和未分配的mcentral被所有的工作線程共同享有存在競爭有鎖機(jī)制//path: /usr/local/go/src/runtime/mcentral.go type mcentral struct { // 互斥鎖 lock mutex // 規(guī)格 sizeclass int32 // 尚有空閑object的mspan鏈表 nonempty mSpanList // 沒有空閑object的mspan鏈表或者是已被mcache取走的msapn鏈表 empty mSpanList // 已累計(jì)分配的對象個(gè)數(shù) nmalloc uint64 }圖中的內(nèi)容和結(jié)構(gòu)體對應(yīng)獲取mspan和歸還流程獲取加鎖從nonempty鏈表找到一個(gè)可用的mspan并將其從nonempty中刪除將取出的mspan加入到empty鏈表將mspan返回給工作線程解鎖歸還加鎖將mspan從empty鏈表刪除將mspan加入到nonempty鏈表解鎖mheapmheap代表Go程序持有的所有堆空間Go程序使用一個(gè)mheap的全局對象_mheap來管理當(dāng)mcentral中沒有空閑的mspan時(shí)會(huì)向mheap申請沒有mheap時(shí)會(huì)向操作系統(tǒng)申請。mheap的主要工作大對象分配內(nèi)存管理未切割的mspan內(nèi)存的分配流程32k直接從mheap上分配16B的對象使用mcache的tiny分配器分配二者之間的首先計(jì)算對象規(guī)格然后從mcache中相應(yīng)的mspan中分配如果mcache中沒有則向mcentral申請mcentral中沒有則向mheap申請mheap中沒有則找操作系統(tǒng)。

相關(guān)新聞

SpringBoot集成OnlyOffice實(shí)現(xiàn)文檔實(shí)時(shí)協(xié)作開發(fā)指南

SpringBoot集成OnlyOffice實(shí)現(xiàn)文檔實(shí)時(shí)協(xié)作開發(fā)指南

1. 項(xiàng)目背景與核心價(jià)值在傳統(tǒng)辦公場景中,Word文檔的協(xié)作往往需要通過郵件反復(fù)發(fā)送附件,版本管理混亂且效率低下。我們團(tuán)隊(duì)最近在開發(fā)一個(gè)知識(shí)管理系統(tǒng)時(shí),就遇到了文檔實(shí)時(shí)協(xié)作的痛點(diǎn)。經(jīng)過技術(shù)選型,最終選擇通過SpringBoot集成Onl…

2026/7/28 20:14:42 閱讀更多
全棧生信分析實(shí)戰(zhàn):Python+R+Docker高效流程搭建

全棧生信分析實(shí)戰(zhàn):Python+R+Docker高效流程搭建

1. 項(xiàng)目概述:全棧生信分析的核心價(jià)值 在生物信息學(xué)領(lǐng)域,Python和R語言就像實(shí)驗(yàn)室里的移液槍和離心機(jī)——前者靈活通用適合流程搭建,后者專精統(tǒng)計(jì)可視化。這個(gè)實(shí)戰(zhàn)指南要解決的問題很明確:讓沒有生信背景的科研人員或轉(zhuǎn)行開發(fā)者&am…

2026/7/28 20:14:42 閱讀更多
構(gòu)建專屬GPT-3 API代理:從架構(gòu)設(shè)計(jì)到RAG集成的完整實(shí)踐

構(gòu)建專屬GPT-3 API代理:從架構(gòu)設(shè)計(jì)到RAG集成的完整實(shí)踐

1. 項(xiàng)目概述:為什么你需要一個(gè)專屬的GPT-3 API如果你正在開發(fā)一個(gè)需要智能對話、內(nèi)容生成或者復(fù)雜文本理解功能的應(yīng)用,直接調(diào)用OpenAI的官方API可能是你腦海中的第一個(gè)念頭。這確實(shí)方便,但當(dāng)你深入項(xiàng)目,尤其是涉及到數(shù)據(jù)隱私、成本…

2026/7/29 6:36:07 閱讀更多
ESP32 GPIO中斷編程實(shí)戰(zhàn):從輪詢到事件驅(qū)動(dòng)的實(shí)時(shí)響應(yīng)優(yōu)化

ESP32 GPIO中斷編程實(shí)戰(zhàn):從輪詢到事件驅(qū)動(dòng)的實(shí)時(shí)響應(yīng)優(yōu)化

1. 項(xiàng)目概述:從輪詢到中斷,ESP32 GPIO的進(jìn)階之路玩過ESP32的朋友,對digitalWrite和digitalRead這兩個(gè)函數(shù)肯定不陌生。點(diǎn)個(gè)燈、讀個(gè)按鍵狀態(tài),用它們輪詢一下,簡單直接。但當(dāng)你開始做更復(fù)雜的項(xiàng)目,比如做一個(gè)…

2026/7/29 6:36:07 閱讀更多
UrbanGS:數(shù)據(jù)驅(qū)動(dòng)的城市綠地規(guī)劃與管理系統(tǒng)

UrbanGS:數(shù)據(jù)驅(qū)動(dòng)的城市綠地規(guī)劃與管理系統(tǒng)

1. UrbanGS項(xiàng)目概述UrbanGS(Urban Green Space)是一個(gè)專注于城市綠地空間規(guī)劃與管理的創(chuàng)新項(xiàng)目。作為一名在城市規(guī)劃領(lǐng)域深耕多年的從業(yè)者,我見證了太多"鋼筋水泥森林"對居民生活質(zhì)量的負(fù)面影響。這個(gè)項(xiàng)目的核心目標(biāo)是通過數(shù)據(jù)驅(qū)動(dòng)…

2026/7/29 6:36:07 閱讀更多
物聯(lián)網(wǎng)設(shè)備低功耗優(yōu)化方案與電源管理技術(shù)

物聯(lián)網(wǎng)設(shè)備低功耗優(yōu)化方案與電源管理技術(shù)

1. 項(xiàng)目背景與核心挑戰(zhàn)在物聯(lián)網(wǎng)設(shè)備井噴式發(fā)展的今天,初級(jí)電池供電設(shè)備的續(xù)航問題日益凸顯。以智能水表、環(huán)境監(jiān)測傳感器、資產(chǎn)追蹤器等典型應(yīng)用為例,這些設(shè)備往往部署在難以更換電池的偏遠(yuǎn)位置,而傳統(tǒng)方案中不可充電的鋰亞電池(L…

2026/7/29 6:36:07 閱讀更多
開發(fā)者生產(chǎn)力:為什么開發(fā)者和管理者理解不同?

開發(fā)者生產(chǎn)力:為什么開發(fā)者和管理者理解不同?

彌合工程師與管理者在開發(fā)者生產(chǎn)力認(rèn)知上的差距。軟件工程管理者都希望開發(fā)者盡可能高效地工作。但在現(xiàn)實(shí)中,我們也常常聽到開發(fā)者抱怨:許多原本為了提升開發(fā)者生產(chǎn)力而引入的系統(tǒng)、工具和流程,實(shí)際效果卻適得其反,甚至讓他們更難…

2026/7/29 6:26:06 閱讀更多
面試官大笑:“一個(gè)任務(wù)拆給 5 個(gè) Subagent 并行跑,不比 1 個(gè)快 5 倍?“我搖頭:“快不了,還可能更慢“

面試官大笑:“一個(gè)任務(wù)拆給 5 個(gè) Subagent 并行跑,不比 1 個(gè)快 5 倍?“我搖頭:“快不了,還可能更慢“

前兩個(gè)月,我在重構(gòu) AlgoMooc 網(wǎng)站過程中,發(fā)現(xiàn)一個(gè)問題:在 Claude Code 里把一個(gè)任務(wù)拆給 5 個(gè) Subagent 并行跑,結(jié)果可能比 1 個(gè) agent 從頭干到尾還慢? 大多數(shù)人的第一反應(yīng)是反過來的:活是并行干的&#…

2026/7/29 0:15:24 閱讀更多
# 鴻蒙 HarmonyOS 應(yīng)用開發(fā)實(shí)戰(zhàn)(第25期)|骰子(Dice Roller)— Unicode 符號(hào)與動(dòng)畫渲染精講

# 鴻蒙 HarmonyOS 應(yīng)用開發(fā)實(shí)戰(zhàn)(第25期)|骰子(Dice Roller)— Unicode 符號(hào)與動(dòng)畫渲染精講

一、應(yīng)用概述 骰子(Dice Roller) 是一款經(jīng)典的休閑娛樂應(yīng)用,模擬了真實(shí)擲骰子的過程。應(yīng)用投擲兩個(gè)骰子(六面標(biāo)準(zhǔn)骰),使用 Unicode 骰面符號(hào)直觀展示每個(gè)骰子的點(diǎn)數(shù),并伴有快速滾動(dòng)的動(dòng)畫效果?!?/p>

2026/7/29 0:15:24 閱讀更多