golang sizeof 占用空间大小

戏子无情 提交于 2020-03-17 01:28:54

某厂面试归来,发现自己落伍了!>>>

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:

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

 

Go 编译器是否会对结构体类型做填充以保证字段对齐

至少对于标准 Go 编译器和 gccgo, 答案是肯定的. 填充是操作系统和编译器相关的.

比如:

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 字节.

Go 规范对类型对齐做一些保证. 规则之一是一个结构体类型的对齐是它字段类型最大的那个的对齐. 所以 T1也是 AMD64 系统 8 字节对齐, i386 系统 4 字节对齐(和 T1.b 类型一样, int64), 并且标准的 Go 编译器将确保类型值的大小是该类型的对齐保证的倍数, 这就是为什么 T1.c 在 AMD64 系统被填充 6 字节, 在 i386 系统被填充 2 字节.

一个结构体中的字段顺序会影响填充, 并且填充会影响后续结构体的大小. 在 AMD64 系统, T1 的大小是 24, 但 T2 的大小是 16.

Go 编译器不会重排结构体字段来减小结构体大小. 这样做会引起一些不可预知的结果. 然而, 程序员可以通过手动重排字段来减少填充.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!