Golang—内存对齐

论坛 期权论坛 脚本     
匿名技术用户   2021-1-6 04:59   11   0

Golang是一种C家族的语言,关于内存对齐和C有大部分相通的地方。如果之前就对内存对齐有了解的话,很容易理解。

先看一个例子吧

package main

import (
 "fmt"
 "unsafe"
)

type part struct {
 a bool
 b int32
 c int8
 d int64
 e byte
}

func main() {
 part1 := part{}
 fmt.Printf("bool size: %d, align: %d, offset: %d\n", unsafe.Sizeof(part1.a), unsafe.Alignof(part1.a), unsafe.Offsetof(part1.a))
 fmt.Printf("int32 size: %d, align: %d, offset: %d\n", unsafe.Sizeof(part1.b), unsafe.Alignof(part1.b), unsafe.Offsetof(part1.b))
 fmt.Printf("int8 size: %d, align: %d, offset: %d\n", unsafe.Sizeof(part1.c), unsafe.Alignof(part1.c), unsafe.Offsetof(part1.c))
 fmt.Printf("int64 size: %d, align: %d, offset: %d\n", unsafe.Sizeof(part1.d), unsafe.Alignof(part1.d), unsafe.Offsetof(part1.d))
 fmt.Printf("byte size: %d, align: %d, offset: %d\n", unsafe.Sizeof(part1.e), unsafe.Alignof(part1.e), unsafe.Offsetof(part1.e))
 fmt.Printf("part1 size: %d, align: %d\n", unsafe.Sizeof(part1), unsafe.Alignof(part1))
}

由结果可以看到bool int8 int32 int64 byte的大小,但是相加的结果并不是part结构体的结果,从结果可以看出来,bool占用了一个字节后,下一个int32类型占用4字节时是有4个字节偏移的,所以一共占用了八个字节,向后推导发现有些类型占用了比类型本身字节更大的空间。导致这个问题的原因就是内存对齐。

1. 为什么会有内存对齐这回事

大部分资料都在说两个原因

  1. 平台问题:并不是所有的硬件平台都能访问任意地址上的任意数据。
  2. 性能问题:访问未对齐内存需要cpu进行两次访问,对齐后只需要一次。

2. 内存对齐原则

  1. 对齐值为系统默认对齐值和类型大小长度的最小值
  2. 结构体内部字段对齐值为默认对齐值和字段最大类型长度的最小值。

3. 内存对齐的使用

由于内存对齐的存在,使得类型按照不同的顺序排列属性可能会得到不同的大小,所以在受限条件下设计类型时需要注意。

package main

import (
 "fmt"
 "unsafe"
)

type part1 struct {
 a bool
 b int32
 c int8
 d int64
 e byte
}
type part2 struct {
 a bool
 e byte
 c int8
 b int32
 d int64
}

func main() {
 p1 := part1{}
 p2 := part2{}
 fmt.Printf("part1 size: %d\n", unsafe.Sizeof(p1))
 fmt.Printf("part2 size: %d\n", unsafe.Sizeof(p2))
}

从结果可以看到,顺序不用对类型体积还是有影响的。下面是对类型内存占用的示意图,-表示占空。

p1 : |a---|bbbb|c---|----|dddd|dddd|e---|----|

p2 : |aec-|bbbb|dddd|dddd|

从上面的示意可以看出part1和part2的占用方式,p2相比p1减少了一半属性占用空间。

参考材料:

1. https://go101.org/article/memory-layout.html

2. https://blog.csdn.net/u011957758/article/details/85059117

3. https://studygolang.com/articles/15540?fr=sidebar


记录每天解决的小问题,积累起来去解决大问题。

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP