• 【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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

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

  • 相关阅读:
    C# XML Helpers实现XML文件操作
    操作系统初始化
    Windows 远程控制 Mac 电脑怎么操作
    m基于FPGA和MATLAB的数字CIC滤波器设计和实现
    【编程题】【Scratch四级】2022.06 成绩查询
    Kubernetes(k8s)使用ingress发布服务
    Pypora导出文件word格式
    arcgis pro批量修改多个矢量的属性
    服务器硬件基础知识
    Windows添加Linux命令
  • 原文地址:https://blog.csdn.net/weixin_45919793/article/details/127579447