【Go】Go结构体内存对齐

Go结构体内存对齐

go的编译器按照指定的规则为结构体去分配内存,以及设置字段在内存中的位置

概念

对齐宽度

对齐宽度是类型的一种属性,他和类型本身以及操作系统有关。一般情况下,对齐宽度和类型大小是一致的。比如byte和bool类型的对齐宽度是1字节,int32类型对齐宽度是4字节。对齐宽度具有上限,在32位系统上,对齐宽度最大为4字节,因此,即便是int64类型,对齐宽度也是4字节,而不是8字节;相应的,在64位系统上,对齐宽度为8字节,即使是string(本身占16字节),对齐宽度也只有8字节。

本身所占字节数

类型指定的大小

实际占用字节数

类型大小+不满足对齐宽度规则时的填充字节数

偏移量

当前字段在内存中的字节编号相对于起始位置的偏移

规则

  1. 每个字段的偏移量必须是其对齐宽度的整数倍
  2. 最终结构体所分配的内存大小是最大齐宽度的整数倍

    最大对齐保证:就是所有字段中最大的对齐宽度

内存对齐的好处

CPU是按照指定字长去读取内存的,内存对齐能够使CPU在一次内存读取操作完成对那些占用内存大小小于等于最大对齐宽度的结构体字段的读取。

  1. 合理的内存对齐可以提高内存读写的性能
  2. 便于实现变量操作的原子性

结论

  1. 结构体字段排列顺序可能最终的结构体大小不同
  2. 最终内存大小一定是所有字段中最大对齐宽度的整数倍
  3. 在构造结构体时候,按照内存大小有序排列,占用的空间更小.

    有序时,由于内存对齐所产生的空白填充更小,空间占用更充分(有序:正序或者逆序)
    例如:
    {a byte, b int8, c int16, d int32, e int64} sum :16B
    省略类型默认:int
    {64 32 16 8 8 } sum 8+4+2+1+1=16B
    {8 64 8 32 16 } sum 8+8+4+4+8=32B
    {8 64 32 8 16 } sum 8+8+4+1+3=24B
    正序,或者逆序,占用最小

package test

import (
	"fmt"
	"testing"
	"unsafe"
)
//{8 64 8 32 16 }
type a struct {
	f1 byte
	f2 int64
	f3 byte
	f4 int32
	f5 int16
}

func TestStructDuiQi(t *testing.T) {
	var s = a{}
	fmt.Println("st")
	fmt.Println("对齐宽度:", unsafe.Alignof(s))
	fmt.Println("本身大小:", unsafe.Sizeof(s))
	fmt.Println("f1")
	fmt.Println("对齐宽度:", unsafe.Alignof(s.f1))
	fmt.Println("本身大小:", unsafe.Sizeof(s.f1))
	fmt.Println("偏 移 量:", unsafe.Offsetof(s.f1))
	fmt.Println("f2")
	fmt.Println("对齐宽度:", unsafe.Alignof(s.f2))
	fmt.Println("本身大小:", unsafe.Sizeof(s.f2))
	fmt.Println("偏 移 量:", unsafe.Offsetof(s.f2))
}
output:
st
对齐宽度: 8
本身大小: 32
f1
对齐宽度: 1
本身大小: 1
偏 移 量: 0
f2
对齐宽度: 8
本身大小: 8
偏 移 量: 8

参考
https://blog.csdn.net/puss0/article/details/110007575
https://blog.csdn.net/weixin_32952295/article/details/112098106

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值