fmt.println(unsafe.sizeof(int64(0))) // "8"記憶體對齊:type sizeofa struct
unsafe.sizeof(sizeofa) // 8
type sizeofc struct
unsafe.sizeof(sizeofc) // 8
unsafe.alignof(sizeofc) // 4
結構體中a byte佔1位元組,c int32佔4位元組. sizeofc佔8位元組
為何會有記憶體對齊?1.並不是所有硬體平台都能訪問任意位址上的任意資料。
2.效能原因 訪問未對齊的記憶體,處理器需要做兩次記憶體訪問,而對齊的記憶體只需訪問一次。
上面**sizeofc中元素一共5個位元組,而實際結構體占8位元組
是因為這個結構體的對齊倍數alignof(sizeofc) = 4.也就是說,結構體占的實際大小必須是4的倍數,也就是8位元組。
type sizeofd structunsafe.sizeof(sizeofd{}) // 16
unsafe.alignof(sizeofd{}) // 4
alignof返回的對齊數是結構體中單位基本型別所佔的記憶體數,不超過8,如果元素是陣列那麼取陣列元素型別所佔的記憶體值而不是整個陣列的值。如圖為sizeofd結構體變數的記憶體布局:
sizeofe中,元素的大小分別為1,8,1,但是實際結構體占24位元組,遠超元素實際大小,因為記憶體對齊原因,最開始分配的8位元組中包含了1位元組的a,剩餘的7位元組不足以放下b,又為b分配了8位元組,剩餘的c獨佔再分配的8位元組。如圖為sizeofe結構體變數的記憶體布局:
換一種寫法,把a,c放到上面,b放到下面。這時sizeofe占用的記憶體變為了16位元組。因為首先分配的8位元組足以放下a和c,省去了8位元組的空間。unsafe.offsetof:返回結構體中元素所在記憶體的偏移量上面乙個結構體中元素的不同順序足以導致記憶體分配的巨大差異。前一種寫法產生了很多的記憶體空洞,導致結構體不夠緊湊,造成記憶體浪費。
如圖為sizeoff結構體變數的記憶體布局:
type sizeofh struct下圖為sizeofh 記憶體布局圖:unsafe.offsetof(sizeofh{}.a) // 0
unsafe.offsetof(sizeofh{}.c) // 2
unsafe.offsetof(sizeofh{}.b) // 8
unsafe.offsetof(sizeofh{}.d) // 16
藍色區域是元素實際所佔記憶體,灰色為記憶體空洞。
x64下1機器位元組=8位元組
golang內建型別占用記憶體大小
從例子中可以看出,結構體中元素不同順序的排列會導致記憶體分配的極大差異,不好的順序會產生許多的記憶體空洞,造成大量記憶體浪費。雖然這幾個函式都在unsafe包中,但是他們並不是不安全的。在需要優化記憶體空間時這幾個函式非常有用。
GO 記憶體對齊
之前遇到過這樣乙個情況 發現問題的結構體並不長這樣,不過為了引出問題,改了一下 type test structfunc main fmt.printf d unsafe.sizeof t 建立乙個結構體,檢視一下其記憶體占用.看結果前先簡單算一下 這麼算下來的話,test結構體占用應該是 1 4 ...
GO語言 記憶體對齊
32位系統,一次可以取32位資料,也就是4位元組,64位是8位元組,即32為作業系統中記憶體是4位元組對齊,而對於64為作業系統是8位元組對齊 記憶體對齊的目的是為了能夠快速的訪問記憶體進行資料訪問,但是會損耗記憶體,即空間換時間 首先 package main import fmt reflect...
記憶體對齊 記憶體對齊規則解釋 記憶體對齊原理
一 記憶體對齊的原因 我們都知道計算機是以位元組 byte 為單位劃分的,理論上來說cpu是可以訪問任一編號的位元組資料的,我們又知道cpu的定址其實是通過位址匯流排來訪問記憶體的,cpu又分為32位和64位,在32位的cpu一次可以處理4個位元組 byte 的資料,那麼cpu實際定址的步長就是4個...