golang的内存对齐

什么是内存对齐

type person struct {
    age int64
    height int64
}
func TestMdemo(t *testing.T) {
    fmt.Println(unsafe.Sizeof(person{}))
    fmt.Println(person{})
}

此时的 打印值为:16,一个64长度int占8字节,两个就是16。

type person struct {
    age int32
    height int64
}
func TestMdemo(t *testing.T) {
    fmt.Println(unsafe.Sizeof(person{}))
    fmt.Println(person{})
}

此时的 打印值为:16,4+8 =12 ,和我们预期不符合。这就是内存对齐现象。

为什么要对齐

那么关于golang如何对齐内存的呢。这里和cpu的访问数据是有关的。
cup访问内存并非按字节读取,而是按照 ”字长“ 来读取

计算机功能的强弱或性能的好坏,不是由某项指标决定的,而是由它的系统结构、指令系统、硬件组成、软件
配置等多方面的因素综合决定的。

计算机以及其相关的软件、硬件设备作为现代科学技术的结晶。应用于工业、商业、金融、教育、科研、军
事、通信及国防建设等国民经济的各个方面。诸多行业的发展对计算机科学愈来愈表现出强烈的依赖性。所以
计算机的评价与检测就十分重要。计算机功能的强弱或性能的好坏,不是由某项指标决定的,而是由它的系统
结构、指令系统、硬件组成、软件配置等多方面的因素综合决定的。

计算机在同一时间内处理的一组二进制数称为一个计算机的“字”,而这组二进制数的位数就是“字长”。在其他
指标相同时,字长越大计算机处理数据的速度就越快。早期的微型计算机的字长一般是8位和16位。586
(Pentium, Pentium Pro, PentiumⅡ,PentiumⅢ,Pentium 4)大多是32位,大多数人都装64位的了。

一般我们现在的服务器都是64位8字节的字长。那么实际上我们cpu读取一个8字节的数据只需要一次读取。

  • 1.增加程序的吞吐
    cpu读取一个变量是由字长开始读取,那么我读取int64的话只需要读一次,如果按照字节长度来读取的话实际上就不太可行,需要读取8次获取一个数据,操作明显的累赘。但是如果说字长太长实际上又会导致部分的空间浪费,为了利于服务器运行并发程序,需要有一个合适的值。
  • 2.利于并发的原子性操作
    我们如何来利用cpu天然的利好与并发程序呢,此时字长就很重要。举个简单例子:我有一个公共变量 counter int64,如果我在不加锁的情况下(我并不在乎最后结果如何),多个线程对值进行改变,此时得到的具体值我们并不能估计出来,但是我们可以知道这个值的内存分布式是正确的。也就是一个single mechine word。 所以这个是一个”并发安全“的操作。大家可以想一下,因为这个值每次只能一次性读出来,一次cpu进行修改,所以在多核线程上世纪就有了一个并发”安全“的操作。此处安全是打引号。我不反对但也不建议这么操作,从业务角度来说你肯定不能对值进行预期。

如何对齐 (对齐系数)

Size and alignment guarantees

type                                 size in bytes
byte, uint8, int8                     1
uint16, int16                         2
uint32, int32, float32                4
uint64, int64, float64, complex64     8
complex128                           16

保证”结构体“最小对齐

    For a variable x of any type: unsafe.Alignof(x) is at least 1.
    For a variable x of struct type: unsafe.Alignof(x) is the largest of all the values unsafe
    .Alignof(x.f) for each field f of x, but at least 1.
    For a variable x of array type: unsafe.Alignof(x) is the same as the alignment of a variable of the array's element type.
  • 任意变量的最小align 系数 >=1
  • 任意结构体变量 ,align系数是其实 struct 中所有参数 align 值的最大一位
  • 对于数组变量:就是单个数组值的align值

其实掌握了align 系数算法我们可以轻松算出struct 的size

利用对齐系数计算结构体大小

我们首先背下来官网的三个原则,就是上面写好了的。

  • 一般来说一个非结构体 的值,string不算,底层是字节数组,它的align =size
  • 一个结构体的align = align_max(struct.filed)
  • align值最小为1

我们来简单计算一下

type person struct {
    i int32
    i1 int32
}

size = size(i) +size(i1) : 8
align = align(i)/align(i1) :4  此时因为两个值的align相同
type person struct {
    i int32
    i1 int32
    i2 int64
}

size = 16      此时应该是size i +size i1 +size i2 = 4+4+8 =16
align = align(i2):8  此时因为两个值的align相同
type person struct {
    i int32
    i1 int64
}

size = 16      此时应该是size i +size i1  = 4+8 =12 ,但是应该size是 align 的倍数,所以最近就是16
align = align(i2):8  此时因为两个值的align相同

计算中的特殊情况

type person struct {
    i int32
    a struct{}
}
size = 8     
align = align(i2):4  此时取值align(4)

这里我们需要特殊说明一下情况:假设a 字段为空,那么如果这个结构体有个方法是返回a,具体如下

type person struct {
    i int32
    a struct{}
}
func (a *person)ted()interface{}{
    return a.a
}

这种情况就有可能出现内存泄露的情况。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容