golang内存对齐原理

内存对齐的现象:

之前没接触过c艹的同学可以先看下面的例子:

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{}))
}

输出结果是:

Size A:32
Size B:24

数据类型

我们接下来先简单讨论下go基本类型的空间分配

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,
}

平台类型则与运行环境相关(比如32位/64位等平台)

// 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
}

注释写的很清楚:

// ...strings and interfaces is 2*WordSize.
//    - The size of slices is 3*WordSize
//    int占据的1个WordSize根据平台会分区分4||8字节

结构体内存对齐

这里来引入一个概念:内存对齐指内存中数据的首地址是CPU单次获取数据大小的整数倍,目的是为了减少cpu读取内存次数,加速操作

结构体对齐规则:

1 结构体成员最大的类型字节数为m,则结构体整体对齐后的字节数应该为m的倍数,不够的在最后面填补占位。

2 结构体某个成员的占用字节数为n, 则它的偏移地址应该是min(n,m)的整数倍。

由上面的类型占用定义可知:

bool 的对齐空间的1字节

int64的对齐空间的8字节

string 的对齐空间的8*2字节

 

所以,我们文章开头的那个demo的占用空间即可计算:

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)
**/

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值