内存对齐

概念

对齐跟数据在内存中的位置有关。如果一个变量的内存地址正好位于它长度的整数倍,他就被称做自然对齐。比如在32cpu下,假设一个整型变量的地址为0x00000004,那它就是自然对齐的。

为什么要字节对齐

  • CPU每次寻址都是要消费时间的,并且CPU访问内存时,并不是逐个字节访问,而是以字长(word size)为单位访问,所以数据结构应该尽可能地在自然边界上对齐,如果访问未对齐的内存,处理器需要做两次内存访问,而对齐的内存访问仅需要一次访问,内存对齐后可以提升性能
  • 有些CPU可以访问任意地址上的任意数据,而有些CPU只能在特定地址访问数据,因此不同硬件平台具有差异性,这样的代码就不具有移植性,如果在编译时,将分配的内存进行对齐,这就具有平台可以移植性了

如何进行对齐?

  • 基本数据类型:地址只要是它的长度的整数倍即可
  • 数组:按照基本数据类型对齐,第一个对齐了后面的自然也就对齐了
  • 联合:按其包含的长度最大的数据类型对齐
  • 结构体:结构体中每个数据类型都要对齐

对齐数

对齐数 =编译器默认值成员自身大小 两者的较小值
32位cpu上默认的指定对齐值是4字节,64位cpu上默认的指定对齐值是8字节

对齐规则

  1. 第一个成员一定对齐,位于结构体变量偏移量(offset)为0的地址处。
  2. 其他成员要对齐到对齐数的整数倍的地址处(当前起始偏移量 % min(成员大小, 对齐数) == 0)
  3. 结构体 总大小必须为最大对齐数(每个成员都有一个对齐数)的整数倍。
  4. 如果嵌套了结构体的情况,先按规则计算出嵌套的结构体大小,最后结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

举例(golang)

// 64位平台,对齐参数是8
type User struct {
 A int32 // 4
 B []int32 // 24 ,切片结构体中每个成员占用8字节
 C string // 16 ,字符串结构体类型占用16字节
 D bool // 1
}

对齐参数是8,int32、[]int32、string、bool对齐值分别是4、8、8、1,占用内存大小分别是4、24、16、1,我们先根据第一条对齐规则分析User:

  • 第一个字段类型是int32,对齐值是4,大小为4,所以放在内存布局中的第一位.
  • 第二个字段类型是[]int32,对齐值是8,大小为24,按照第一条规则,偏移量应该是成员大小24与对齐值8中较小那个的整数倍,那么偏移量就是8,所以4-7位会由编译进行填充,一般为0值,也称为空洞,第9到32位为第二个字段B.
  • 第三个字段类型是string,对齐值是8,大小为16,所以他的内存偏移值必须是8的倍数,因为user前两个字段就已经排到了第32位,所以offset为32正好是8的倍数,不要填充,从32位到48位是第三个字段C.
  • 第四个字段类型是bool,对齐值是1,大小为1,所以他的内存偏移值必须是1的倍数,因为user前两个字段就已经排到了第48位,所以下一位的偏移量正好是48,正好是字段D的对齐值的倍数,不用填充,可以直接排列到第四个字段,也就是从48到第49位是第三个字段D

©著作权归作者所有:来自51CTO博客作者Golang梦工厂的原创作品,请联系作者获取转载授权,否则将追究法律责任
详解内存对齐
https://blog.51cto.com/u_14523732/5707302

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 问题 在开始之前,希望你计算一下 Part1 共占用的大小是多少呢? 输出结果: 这么一算,Part1 这一个结构...
    羋学僧阅读 3,749评论 3 2
  • unsafe 包简单说明 unsafe,顾名思义,是不安全的,Go定义这个包名也是这个意思,让我们尽可能的不要使用...
    Gopherzhang阅读 5,472评论 8 3
  • 原文地址:在 Go 中恰到好处的内存对齐 问题 在开始之前,希望你计算一下 Part1 共占用的大小是多少呢? 输...
    EDDYCJY阅读 4,793评论 1 11
  • 本次主要讨论三个问题: 什么是内存对齐 内存对齐的好处 如何对齐 内存对齐 内存对齐是一种提高内存访问速度的策略。...
    一个人在路上走下去阅读 5,469评论 0 2
  • 1. 介绍 CPU把内存当成是一块一块的,块的大小可以是2,4,8,16字节大小,因此CPU在读取内存时是一块一块...
    husky_1阅读 5,022评论 0 1

友情链接更多精彩内容