golang内存对齐原理
之前没接触过c艹的同学可以先看下面的例子:
<pre><code class="language-Go">type A struct { a bool b string c bool } type B struct { a bool c bool b string } func main() { fmt.Printf("Size A:%d\n", unsafe.Sizeof(A{})) fmt.Printf("Size B:%d\n", unsafe.Sizeof(B{})) }</code></pre>输出结果是:
<pre><code>Size A:32 Size B:24</code></pre> <h2>数据类型</h2>我们接下来先简单讨论下go基本类型的空间分配
go底层对于数据类型的内存占用做了如下定义:<em>基本类型</em>和<em>平台类型</em>
基本类型是直接标识出类型占用字节数的:
<pre><code class="language-Go">var basicSizes = [...]byte{ Bool: 1, Int8: 1, Int16: 2, Int32: 4, Int64: 8, Uint8: 1, Uint16: 2, Uint32: 4, Uint64: 8, Float32: 4, Float64: 8, Complex64: 8, Complex128: 16, }</code></pre>平台类型则与运行环境相关(比如32位/64位等平台)
<pre><code class="language-Go">// StdSizes is a convenience type for creating commonly used Sizes. // It makes the following simplifying assumptions: // // - The size of explicitly sized basic types (int16, etc.) is the // specified size. // - The size of strings and interfaces is 2*WordSize. // - The size of slices is 3*WordSize. // - The size of an array of n elements corresponds to the size of // a struct of n consecutive fields of the array's element type. // - The size of a struct is the offset of the last field plus that // field's size. As with all element types, if the struct is used // in an array its size must first be aligned to a multiple of the // struct's alignment. // - All other types have size WordSize. // - Arrays and structs are aligned per spec definition; all other // types are naturally aligned with a maximum alignment MaxAlign. // // *StdSizes implements Sizes. // type StdSizes struct { WordSize int64 // word size in bytes - must be >= 4 (32bits) MaxAlign int64 // maximum alignment in bytes - must be >= 1 }</code></pre>注释写的很清楚:
// ...strings and interfaces is 2*WordSize.
// - The size of slices is 3*WordSize
// int占据的1个WordSize根据平台会分区分4||8字节
这里来引入一个概念:内存对齐指<u>内存中数据的首地址是CPU单次获取数据大小的整数倍,目的是为了减少cpu读取内存次数,加速操作</u>
结构体对齐规则:
1 结构体成员最大的类型字节数为m,则结构体整体对齐后的字节数应该为m的倍数,不够的在最后面填补占位。
2 结构体某个成员的占用字节数为n, 则它的偏移地址应该是min(n,m)的整数倍。
由上面的类型占用定义可知:
bool 的对齐空间的1字节
int64的对齐空间的8字节
string 的对齐空间的8*2字节
<em>所以,我们文章开头的那个demo的占用空间即可计算:</em>
<pre><code>type A struct { a bool b string c bool } /** A内存占用:32字节 bool 1byte 补7byte string 8*2byte(指针8byte, len 8byte,两个int) bool 1byte 补7byte **/ type B struct { a bool c bool b string } /** B内存占用:24字节 bool 1byte bool 1byte 补8-1-1=6byte string 8*2byte(指针8byte, len 8byte,两个int) **/</code></pre>到此这篇关于“golang内存对齐原理”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!
您可能感兴趣的文章:
[译]如果对齐内存的写入是原子性的,为什么我们还需要sync/atomic包
Go的内存对齐和指针运算详解和实践
golang内存对齐原理
Golang 切片容量(cap)增长探秘
内存池原理详解
Golang是否真的没有指针运算?
Go内存管理(一)TCMalloc内存管理原理
golang url 收集
Go 内存管理(一)TCMalloc内存管理原理
年度最佳【golang】内存分配详解