欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Golang內(nèi)存分配機(jī)制詳解

 更新時(shí)間:2023年12月20日 08:59:30   作者:路多辛  
Go 語(yǔ)言的內(nèi)存分配機(jī)制是理解和優(yōu)化 Go 程序性能的關(guān)鍵,在 Go 中,內(nèi)存管理是自動(dòng)進(jìn)行的,這得益于 Go 的垃圾回收機(jī)制,了解內(nèi)存如何分配和回收,可以幫助我們寫(xiě)出更高性能的代碼,本文將深入講解下 Go 內(nèi)存分配機(jī)制,需要的朋友可以參考下

內(nèi)存分配的基本原理

在計(jì)算機(jī)科學(xué)中,內(nèi)存分配是指為程序中的變量和數(shù)據(jù)結(jié)構(gòu)分配存儲(chǔ)空間的過(guò)程。在 Golang 中,內(nèi)存分配主要由 Go 運(yùn)行時(shí)系統(tǒng)(runtime)負(fù)責(zé),主要包括以下兩個(gè)方面:

  • 堆內(nèi)存分配:堆內(nèi)存是用于動(dòng)態(tài)分配的內(nèi)存區(qū)域,主要用于存儲(chǔ)程序運(yùn)行過(guò)程中創(chuàng)建的對(duì)象和數(shù)據(jù)結(jié)構(gòu)。通過(guò) new、make 等函數(shù)或者使用指針進(jìn)行內(nèi)存分配時(shí),都會(huì)在堆上分配內(nèi)存。
  • 棧內(nèi)存分配:棧內(nèi)存是用于存放函數(shù)調(diào)用時(shí)的局部變量和返回地址等信息的內(nèi)存區(qū)域?;绢?lèi)型(如整型、浮點(diǎn)型、布爾型等)和小對(duì)象(通常小于 64 字節(jié))的內(nèi)存分配通常發(fā)生在棧上。

Go 使用了一個(gè)稱為“tcmalloc”(thread-caching malloc)的內(nèi)存分配器,最初由 Google 開(kāi)發(fā)。tcmalloc 的設(shè)計(jì)目標(biāo)是減少全局鎖的競(jìng)爭(zhēng),提高多線程程序的性能。Go 的內(nèi)存分配器是基于 tcmalloc 概念的一個(gè)實(shí)現(xiàn),有幾個(gè)關(guān)鍵的組成部分:

  • M: 代表操作系統(tǒng)線程(machine)。
  • P: 代表處理器(processor),管理著一組本地緩存。
  • G: 代表 goroutine,是 Go 程序執(zhí)行的最小單位。

每個(gè) P 都有自己的內(nèi)存緩存(mcache),用于小對(duì)象的快速分配。當(dāng) mcache 用完時(shí),P 會(huì)從中心緩存(mcentral)獲取內(nèi)存。如果 mcentral 也不足,內(nèi)存分配器會(huì)向操作系統(tǒng)請(qǐng)求更多內(nèi)存。

Golang 內(nèi)存分配的機(jī)制

  • 小對(duì)象分配,小對(duì)象(一般小于 32KB)的分配是通過(guò) P 的 mcache 來(lái)進(jìn)行的。mcache 包含了一系列固定大小的內(nèi)存塊,稱為“span”。每個(gè) span 專門(mén)用于一種大小的對(duì)象。當(dāng)一個(gè) goroutine 需要分配一個(gè)小對(duì)象時(shí),就會(huì)查找對(duì)應(yīng)大小的 span,并從中分配一塊內(nèi)存。
  • 大對(duì)象分配,大對(duì)象(一般大于 32KB)的分配不經(jīng)過(guò) mcache,而是直接從堆上分配。這是因?yàn)榇髮?duì)象的分配和回收比小對(duì)象更少,直接在堆上操作可以減少碎片和管理的復(fù)雜性。
  • 內(nèi)存分配優(yōu)化,為了減少內(nèi)存分配的成本,Go 的內(nèi)存分配器會(huì)進(jìn)行一些優(yōu)化:
    • 大小類(lèi)分配:為了減少內(nèi)存碎片和提高內(nèi)存重用,Go 將對(duì)象分為不同的大小類(lèi)。每個(gè)大小類(lèi)的對(duì)象都會(huì)分配到對(duì)應(yīng)的 span 中。
    • 對(duì)象對(duì)齊:Go 保證對(duì)象在內(nèi)存中對(duì)齊,有助于提高 CPU 緩存的效率。
    • 批量分配:當(dāng) mcache 中的 span 用完時(shí),不是一次只獲取一個(gè)新的 span,而是批量地從 mcentral 獲取多個(gè) span,可以減少與 mcentral 的交互次數(shù)。

垃圾回收(GC)

Go 的垃圾回收器是一個(gè)并發(fā)的、標(biāo)記-清除(mark-sweep)垃圾回收器。垃圾回收分為幾個(gè)階段:

  • 標(biāo)記階段:垃圾回收器會(huì)停止所有的 goroutine(STW - stop the world),快速掃描棧和全局變量,標(biāo)記所有可達(dá)的對(duì)象。
  • 并發(fā)標(biāo)記:goroutine 被恢復(fù)執(zhí)行,同時(shí)垃圾回收器在后臺(tái)并發(fā)地完成標(biāo)記工作。
  • 清除階段:清除未被標(biāo)記的對(duì)象,通常也是并發(fā)進(jìn)行的。

Go 的垃圾回收器設(shè)計(jì)為低延遲,會(huì)盡量減少對(duì)程序執(zhí)行的干擾。

內(nèi)存逃逸

在 Go 中,編譯器會(huì)盡量在棧上分配內(nèi)存,因?yàn)闂I系膬?nèi)存分配和回收非??臁H欢?,并不是所有的內(nèi)存分配都可以在棧上完成。當(dāng)編譯器無(wú)法保證對(duì)象的生命周期僅限于其定義的作用域時(shí),會(huì)將這些對(duì)象分配到堆上,這個(gè)過(guò)程稱為“內(nèi)存逃逸”。

內(nèi)存分配的影響因素

內(nèi)存分配的性能可能受到多種因素的影響,包括以下幾個(gè)方面:

  • 內(nèi)存分配頻率:頻繁的內(nèi)存分配和回收會(huì)增加垃圾回收器的工作量,從而影響性能。
  • 對(duì)象大?。捍髮?duì)象的分配通常比小對(duì)象慢,因?yàn)椴唤?jīng)過(guò) mcache。
  • 對(duì)象生命周期:長(zhǎng)生命周期的對(duì)象可能會(huì)導(dǎo)致內(nèi)存占用增加,因?yàn)椴粫?huì)被頻繁回收。

內(nèi)存分配的最佳實(shí)踐

為了優(yōu)化內(nèi)存分配,可以從以下幾個(gè)方面著手:

  • 重用對(duì)象:通過(guò)重用對(duì)象來(lái)減少分配次數(shù)。
  • 池化資源:使用 sync.Pool 來(lái)池化可重用的對(duì)象。
  • 避免內(nèi)存逃逸:通過(guò)減少指針的使用和閉包捕獲來(lái)避免不必要的內(nèi)存逃逸。
  • 合理的數(shù)據(jù)結(jié)構(gòu):選擇合適的數(shù)據(jù)結(jié)構(gòu)來(lái)減少內(nèi)存的占用和碎片。

小結(jié)

Go 的內(nèi)存分配器是為并發(fā)和多線程設(shè)計(jì)的,通過(guò)一系列優(yōu)化來(lái)提供高效的內(nèi)存分配。內(nèi)存分配的性能不僅取決于分配器本身,還取決于程序的設(shè)計(jì)和編碼方式。在日常開(kāi)發(fā)中,可以使用工具(如 pprof)來(lái)分析和優(yōu)化程序的內(nèi)存使用情況。通過(guò)實(shí)踐和分析,更深入地理解和掌握 Go 的內(nèi)存管理機(jī)制。

以上就是Golang內(nèi)存分配機(jī)制詳解的詳細(xì)內(nèi)容,更多關(guān)于Golang內(nèi)存分配機(jī)制的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Go通用的?MapReduce?工具函數(shù)詳解

    Go通用的?MapReduce?工具函數(shù)詳解

    本文介紹了使用Go語(yǔ)言實(shí)現(xiàn)的MapReduce框架,特別是在AWSS3?SDK的MultiPartUpload功能中的應(yīng)用,包括并發(fā)上傳和錯(cuò)誤處理策略,詳細(xì)解釋了如何通過(guò)并發(fā)goroutines提高上傳效率,并通過(guò)MapReduce模型優(yōu)化代碼結(jié)構(gòu)和處理流程,感興趣的朋友跟隨小編一起看看吧
    2024-09-09
  • GoLang unsafe包詳細(xì)講解

    GoLang unsafe包詳細(xì)講解

    從golang的定義來(lái)看,unsafe 是類(lèi)型安全的操作。顧名思義,它應(yīng)該非常謹(jǐn)慎地使用; unsafe可能很危險(xiǎn),但也可能非常有用。例如,當(dāng)使用系統(tǒng)調(diào)用和Go結(jié)構(gòu)必須具有與C結(jié)構(gòu)相同的內(nèi)存布局時(shí),您可能別無(wú)選擇,只能使用unsafe
    2022-10-10
  • Golang通道的無(wú)阻塞讀寫(xiě)的方法示例

    Golang通道的無(wú)阻塞讀寫(xiě)的方法示例

    這篇文章主要介紹了Golang通道的無(wú)阻塞讀寫(xiě)的方法示例,詳細(xì)的介紹了哪些情況會(huì)存在阻塞,以及如何使用select解決阻塞,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2018-11-11
  • 淺析Go語(yǔ)言中的緩沖區(qū)及其在fmt包中的應(yīng)用

    淺析Go語(yǔ)言中的緩沖區(qū)及其在fmt包中的應(yīng)用

    這篇文章主要為大家詳細(xì)介紹了Go語(yǔ)言中的緩沖區(qū)及其在fmt包中的應(yīng)用的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2024-01-01
  • Golang 使用接口實(shí)現(xiàn)泛型的方法示例

    Golang 使用接口實(shí)現(xiàn)泛型的方法示例

    這篇文章主要介紹了Golang 使用接口實(shí)現(xiàn)泛型的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • Golang之sync.Pool使用詳解

    Golang之sync.Pool使用詳解

    這篇文章主要介紹了Golang之sync.Pool使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • 在Golang代碼中如何自動(dòng)生成版本號(hào)的方法示例

    在Golang代碼中如何自動(dòng)生成版本號(hào)的方法示例

    這篇文章主要給大家介紹了在Golang代碼中如何自動(dòng)生成版本號(hào)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。
    2017-07-07
  • Go?mod?replace使用方法及常見(jiàn)問(wèn)題分析

    Go?mod?replace使用方法及常見(jiàn)問(wèn)題分析

    這篇文章主要為大家介紹了Go?mod?replace使用方法及常見(jiàn)問(wèn)題分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • Go語(yǔ)言處理超大字符串型整數(shù)加減經(jīng)典面試詳解

    Go語(yǔ)言處理超大字符串型整數(shù)加減經(jīng)典面試詳解

    這篇文章主要為大家介紹了Go語(yǔ)言處理超大字符串型整數(shù)加減經(jīng)典面試示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • Golang實(shí)現(xiàn)Redis過(guò)期時(shí)間實(shí)例探究

    Golang實(shí)現(xiàn)Redis過(guò)期時(shí)間實(shí)例探究

    這篇文章主要介紹了Golang實(shí)現(xiàn)Redis過(guò)期時(shí)間實(shí)例探究,
    2024-01-01

最新評(píng)論