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

一文探索Go語(yǔ)言中的內(nèi)存對(duì)齊

 更新時(shí)間:2024年11月22日 15:58:41   作者:左詩(shī)右碼  
在 Go 語(yǔ)言中,內(nèi)存對(duì)齊是一個(gè)經(jīng)常被忽略但非常重要的概念,本文將通過(guò)一個(gè)簡(jiǎn)單的例子來(lái)探討 Go 語(yǔ)言中的內(nèi)存對(duì)齊機(jī)制,感興趣的可以了解下

在 Go 語(yǔ)言中,內(nèi)存對(duì)齊是一個(gè)經(jīng)常被忽略但非常重要的概念。理解內(nèi)存對(duì)齊不僅可以幫助我們寫出更高效的代碼,還能避免一些潛在的性能陷阱。

在這篇文章中,我們將通過(guò)一個(gè)簡(jiǎn)單的例子來(lái)探討 Go 語(yǔ)言中的內(nèi)存對(duì)齊機(jī)制,以及為什么相似的結(jié)構(gòu)體在內(nèi)存中會(huì)占用不同的大小。

示例代碼

我們先來(lái)看一段代碼:

package memory_alignment

import (
	"fmt"
	"unsafe"
)

type A struct {
	a int8
	b int8
	c int32
	d string
	e string
}

type B struct {
	a int8
	e string
	c int32
	b int8
	d string
}

func Run() {
	var a A
	var b B
	fmt.Printf("a size: %v \n", unsafe.Sizeof(a))
	fmt.Printf("b size: %v \n", unsafe.Sizeof(b))
	// a size: 40
	// b size: 48
}

在這個(gè)例子中,我們定義了兩個(gè)結(jié)構(gòu)體 AB。它們的字段基本相同,只是排列順序不同。然后,我們使用 unsafe.Sizeof 來(lái)查看這兩個(gè)結(jié)構(gòu)體在內(nèi)存中的大小。

結(jié)果卻令人驚訝:結(jié)構(gòu)體 A 的大小是 40 字節(jié),而結(jié)構(gòu)體 B 的大小是 48 字節(jié)。為什么會(huì)出現(xiàn)這樣的差異呢?這就是我們今天要討論的內(nèi)存對(duì)齊的作用。

內(nèi)存對(duì)齊概念

內(nèi)存對(duì)齊是指編譯器為了優(yōu)化內(nèi)存訪問(wèn)速度,而對(duì)數(shù)據(jù)在內(nèi)存中的位置進(jìn)行調(diào)整的一種策略。不同類型的數(shù)據(jù)在內(nèi)存中的對(duì)齊要求不同,例如:

  • int8 類型的變量通常對(duì)齊到 1 字節(jié)邊界。
  • int32 類型的變量通常對(duì)齊到 4 字節(jié)邊界。
  • 指針(如 string)通常對(duì)齊到 8 字節(jié)邊界。

為了滿足這些對(duì)齊要求,編譯器可能會(huì)在結(jié)構(gòu)體的字段之間插入一些“填充”字節(jié),從而確保每個(gè)字段都能正確對(duì)齊。

結(jié)構(gòu)體內(nèi)存布局解析

讓我們深入分析一下 AB 兩個(gè)結(jié)構(gòu)體的內(nèi)存布局,看看編譯器是如何為它們分配內(nèi)存的。

結(jié)構(gòu)體 A 的內(nèi)存布局

| a (int8) | b (int8) | padding (2 bytes) | c (int32) | d (string, 8 bytes) | e (string, 8 bytes) |
  • abint8 類型,各占 1 字節(jié)。
  • cint32 類型,需要 4 字節(jié)對(duì)齊,b 后面會(huì)有 2 個(gè)填充字節(jié)。
  • destring 類型,各占 8 字節(jié)。

總大小為:1 + 1 + 2 + 4 + 8 + 8 = 24 字節(jié)。

結(jié)構(gòu)體 B 的內(nèi)存布局

| a (int8) | padding (7 bytes) | e (string, 8 bytes) | c (int32) | padding (4 bytes) | b (int8) | padding (3 bytes) | d (string, 8 bytes) |
  • aint8 類型,占 1 字節(jié),后面有 7 個(gè)填充字節(jié),以便 e 能夠?qū)R到 8 字節(jié)邊界。
  • cint32 類型,需要 4 字節(jié)對(duì)齊,因此在 c 后面沒(méi)有填充。
  • bint8 類型,需要填充 3 個(gè)字節(jié)來(lái)對(duì)齊到 d 的 8 字節(jié)邊界。

總大小為:1 + 7 + 8 + 4 + 4 + 1 + 3 + 8 = 36 字節(jié)。

請(qǐng)注意,Go 編譯器可能會(huì)將 de 視為 8 字節(jié)對(duì)齊類型(取決于系統(tǒng)和編譯器的實(shí)現(xiàn)),因此總大小可能是 48 字節(jié)。

如何優(yōu)化結(jié)構(gòu)體內(nèi)存布局

為了減少結(jié)構(gòu)體的內(nèi)存占用,我們可以按照字段的對(duì)齊要求來(lái)重新排列字段。例如:

先聲明大的字段(如 stringint32),然后是小的字段(如 int8),可以減少內(nèi)存中的填充字節(jié)。

我們可以將 B 結(jié)構(gòu)體改成以下形式:

type OptimizedB struct {
    e string
    d string
    c int32
    a int8
    b int8
}

這樣可以減少內(nèi)存填充,從而優(yōu)化內(nèi)存占用。

總結(jié)

內(nèi)存對(duì)齊是編譯器優(yōu)化內(nèi)存訪問(wèn)速度的一個(gè)重要策略。雖然它對(duì)大多數(shù)應(yīng)用程序的影響可能較小,但在高性能場(chǎng)景或內(nèi)存受限的環(huán)境中,理解并優(yōu)化內(nèi)存對(duì)齊可能會(huì)帶來(lái)顯著的性能提升。

在 Go 語(yǔ)言中,了解結(jié)構(gòu)體的內(nèi)存對(duì)齊規(guī)則,合理排列結(jié)構(gòu)體字段順序,不僅可以提高程序的性能,還能減少內(nèi)存的浪費(fèi)。這是一種簡(jiǎn)單而有效的優(yōu)化手段,希望大家在以后的編程實(shí)踐中能夠靈活運(yùn)用。

到此這篇關(guān)于一文探索Go語(yǔ)言中的內(nèi)存對(duì)齊的文章就介紹到這了,更多相關(guān)Go內(nèi)存對(duì)齊內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 一鍵定位Golang線上服務(wù)內(nèi)存泄露的秘籍

    一鍵定位Golang線上服務(wù)內(nèi)存泄露的秘籍

    內(nèi)存泄露?別讓它拖垮你的Golang線上服務(wù)!快速掌握Go語(yǔ)言服務(wù)內(nèi)存泄漏排查秘籍,從此問(wèn)題無(wú)處遁形,一文讀懂如何精準(zhǔn)定位與有效解決Golang應(yīng)用中的內(nèi)存問(wèn)題,立即閱讀,讓性能飛升!
    2024-01-01
  • Mac GoLand打不開(閃退)也不報(bào)錯(cuò)的解決方案

    Mac GoLand打不開(閃退)也不報(bào)錯(cuò)的解決方案

    這篇文章主要介紹了Mac GoLand打不開(閃退)也不報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-04-04
  • Go單元測(cè)試對(duì)數(shù)據(jù)庫(kù)CRUD進(jìn)行Mock測(cè)試

    Go單元測(cè)試對(duì)數(shù)據(jù)庫(kù)CRUD進(jìn)行Mock測(cè)試

    這篇文章主要為大家介紹了Go單元測(cè)試對(duì)數(shù)據(jù)庫(kù)CRUD進(jìn)行Mock測(cè)試的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • Go用兩個(gè)協(xié)程交替打印100以內(nèi)的奇偶數(shù)的方法詳解

    Go用兩個(gè)協(xié)程交替打印100以內(nèi)的奇偶數(shù)的方法詳解

    這篇文章主要給大家詳細(xì)介紹了Go用兩個(gè)協(xié)程交替打印100以內(nèi)的奇偶數(shù)的示例代碼,文中給大家介紹了兩個(gè)實(shí)現(xiàn)方法,使用無(wú)緩沖的channel和設(shè)置GOMAXPROCS=1,介紹的非常詳細(xì),需要的朋友可以參考下
    2023-08-08
  • Golang實(shí)現(xiàn)Directional Channel(定向通道)

    Golang實(shí)現(xiàn)Directional Channel(定向通道)

    這篇文章主要介紹了Golang實(shí)現(xiàn)Directional Channel(定向通道),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • Go語(yǔ)言中Slice常見(jiàn)陷阱與避免方法詳解

    Go語(yǔ)言中Slice常見(jiàn)陷阱與避免方法詳解

    這篇文章主要為大家詳細(xì)介紹的是 Go 語(yǔ)言中的 Slice 的常見(jiàn)陷阱以及如何避免這些錯(cuò)誤,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以學(xué)習(xí)一下
    2023-02-02
  • go語(yǔ)言中if語(yǔ)句用法實(shí)例

    go語(yǔ)言中if語(yǔ)句用法實(shí)例

    這篇文章主要介紹了go語(yǔ)言中if語(yǔ)句用法,以實(shí)例形式分析了if語(yǔ)句的定義及使用技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-02-02
  • go-zero?組件布隆過(guò)濾器使用示例詳解

    go-zero?組件布隆過(guò)濾器使用示例詳解

    這篇文章主要為大家介紹了go-zero組件介紹之布隆過(guò)濾器使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • golang生成vcf通訊錄格式文件詳情

    golang生成vcf通訊錄格式文件詳情

    這篇文章主要介紹了golang生成vcf通訊錄格式文件詳情,?VCF是通訊錄格式文件,一般需要用手機(jī)通訊錄導(dǎo)入導(dǎo)出的文件格式都是vcf格式。?下面詳細(xì)內(nèi)容介紹需要的小伙伴可以參考一下
    2022-03-03
  • go項(xiàng)目中環(huán)境變量的配置

    go項(xiàng)目中環(huán)境變量的配置

    本文主要介紹了go項(xiàng)目中環(huán)境變量的配置,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-07-07

最新評(píng)論