go语言对齐内存 go语言gc( 五 )


使用 Go 语言开发的开源项目非常多 。早期的 Go 语言开源项目只是通过 Go 语言与传统项目进行C语言库绑定实现,例如 Qt、Sqlite 等 。
后期的很多项目都使用 Go 语言进行重新原生实现 , 这个过程相对于其他语言要简单一些 , 这也促成了大量使用 Go 语言原生开发项目的出现 。
内存对齐问题1.平台原因(移植原因): 不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能
在某些地址处取某些特定类型的数据,否则抛出硬件异常 。
2.性能原因: 数据结构应该尽可能地在自然边界上对齐 。原因在于 , 为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问 。(如果是对齐的,那么CPU不需要跨越两个操作字,不是对齐的则需要访问两个操作字才能拼接出需要的内存地址)
指针的大小一般是一个机器字的大小
通过Go语言的structlayout工具,可以得出下图
这些类型在之前的 slice 、 map 、 interface 已经介绍过了,也特意强调过,makehmap函数返回的是一个指针,因此map的对齐为一个机器字.
回头看看 sync.pool的防止copy的空结构体字段,也是放在第一位,破案了 。
计算机结构可能会要求内存地址 进行对齐;也就是说,一个变量的地址是一个因子的倍数,也就是该变量的类型是对齐值 。
函数Alignof接受一个表示任何类型变量的表达式作为参数,并以字节为单位返回变量(类型)的对齐值 。对于变量x:
这是因为int64在bool之后未对齐 。
它是32位对齐的,但不是64位对齐的,因为我们使用的是32位系统,因此实际上只是两个32位值并排在一起 。
● 内存对齐是为了cpu更高效访问内存中数据
● 结构体对齐依赖类型的大小保证和对齐保证
● 地址对齐保证是:如果类型 t 的对齐保证是 n,那么类型 t 的每个值的地址在运行时必须是 n 的倍数 。
● struct内字段如果填充过多,可以尝试重排,使字段排列更紧密,减少内存浪费
● 零大小字段要避免作为struct最后一个字段,会有内存浪费
● 32位系统上对64位字的原子访问要保证其是8bytes对齐的;当然如果不必要的 话,还是用加锁(mutex)的方式更清晰简单
图解go-内存对齐
doc-pdf
关于go语言对齐内存和go语言gc的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站 。

推荐阅读