go结构体大小

在seaweedfs中,存储数据使用的核心结构体为needle,而对于golang中的结构体,计算它的内存占用大小和C是一样的,会使用内存对齐的方法,计算结构体大小的方式参考Sizeof struct in Go
C语言结构体占用空间内存大小解析
The size depends on the types it consists of and the order of the fields in the struct (because different padding will be used). This means that two structs with the same fields can have different size.

For example this struct will have a size of 32

1
2
3
4
5
struct {
a bool
b string
c bool
}

and a slight modification will have a size of 24 (a 25% difference just due to a more compact ordering of fields)

1
2
3
4
5
struct {
a bool
c bool
b string
}


As you see from the pictures, in the second example we removed one of the paddings and moved a field to take advantage of the previous padding. An alignment can be 1, 2, 4, or 8. A padding is the space that was used to fill in the variable to fill the alignment (basically wasted space).

Knowing this rule and remembering that:

bool, int8/uint8 take 1 chunk
int16, uint16 - 2 chunks
int32, uint32, float32 - 4 chunks
int64, uint64, float64, pointer - 8 chunks
string - 16 chunks (2 alignments of 8 chunks)
any slice takes 24 chunks (3 alignments of 8 chunks). So []bool, [][][]string are the same (do not forget to reread the citation I added in the beginning)
array of length n takes n * type it takes of chunks.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
type Needle struct {
trueCookie uint32 `comment:"random number to mitigate brute force lookups"`
trueId uint64 `comment:"needle id"`
trueSize uint32 `comment:"sum of DataSize,Data,NameSize,Name,MimeSize,Mime"`
trueDataSize uint32 `comment:"Data size"`
trueData []byte `comment:"The actual file data"`
trueFlags byte `comment:"boolean flags"`
trueNameSize uint8
trueName []byte `comment:"maximum 256 characters"`
trueMimeSize uint8
trueMime []byte `comment:"maximum 256 characters"`
trueLastModified uint64 //only store LastModifiedBytesLength bytes, which is 5 bytes to disk
trueTtl *TTL
trueChecksum CRC `comment:"CRC32 to check integrity"`
truePadding []byte `comment:"Aligned to 8 bytes"`
truerawBlock *Block // underlying supporing []byte, fetched and released into a pool
}