golang sizeof 佔用空間大小

C語言中,能夠使用sizeof()計算變量或類型佔用的內存大小。在Go語言中,也提供了相似的功能, 不過只能查看變量佔用空間大小。具體使用舉例以下。程序員

package main

import (
        "fmt"
        "unsafe"

)

type Man struct {
        Name     string
        Age      int
}

func main() {

        m := Man{Name:"John", Age:20}


        fmt.Println("man size:", unsafe.Sizeof(m))
        fmt.Println("name size:", unsafe.Sizeof(m.Name))
        fmt.Println("age size:", unsafe.Sizeof(m.Age))
}

output:golang

man size: 24
name size: 16
age size: 8c#

 

Go 編譯器是否會對結構體類型作填充以保證字段對齊

至少對於標準 Go 編譯器和 gccgo, 答案是確定的. 填充是操做系統和編譯器相關的.spa

好比:操作系統

type T1 struct {
	a int8
	// 7 bytes padded on AMD64 OS and pad 3 bytes padded on i386 OS here
	b int64
	c int16
	// 6 bytes padded on AMD64 OS and pad 2 bytes padded on i386 OS here
}

type T2 struct {
	a int8
	// 1 byte padded on both AMD64 and i386 OS here
	c int16
	// 4 bytes padded on AMD64 OS here. No padding on i386 OS
	b int64
}

T1.b 內存中的地址值在 AMD64 系統必須的是 8 字節對齊的, i386 系統是 4 字節對齊的. 這就是爲何 T1.a 在 AMD64 系統被填充 7 字節, 在 i386 系統被填充 3 字節.code

Go 規範對類型對齊作一些保證. 規則之一是一個結構體類型的對齊是它字段類型最大的那個的對齊. 因此 T1也是 AMD64 系統 8 字節對齊, i386 系統 4 字節對齊(和 T1.b 類型同樣, int64), 而且標準的 Go 編譯器將確保類型值的大小是該類型的對齊保證的倍數, 這就是爲何 T1.c 在 AMD64 系統被填充 6 字節, 在 i386 系統被填充 2 字節.內存

一個結構體中的字段順序會影響填充, 而且填充會影響後續結構體的大小. 在 AMD64 系統, T1 的大小是 24, 但 T2 的大小是 16.get

Go 編譯器不會重排結構體字段來減少結構體大小. 這樣作會引發一些不可預知的結果. 然而, 程序員能夠經過手動重排字段來減小填充.編譯器

相關文章
相關標籤/搜索