In Go, memory alignment is an often overlooked but very important concept. Understanding memory alignment not only helps us write more efficient code, but also avoids some potential performance pitfalls.
In this article, we will use a simple example to explore the memory alignment mechanism in Go and why similar structures occupy different sizes in memory.
Sample code
Let's first look at a piece of code:
package memory_alignment import ( "fmt" "unsafe" ) type A struct { a int8 b int8 c int32 d string e string } type B struct { a int8 e string c int32 b int8 d string } func Run() { var a A var b B ("a size: %v \n", (a)) ("b size: %v \n", (b)) // a size: 40 // b size: 48 }
In this example, we define two structuresA
andB
. Their fields are basically the same, but the arrangement order is different. Then, we useLet's see the size of these two structures in memory.
The result is surprising: the structureA
The size is 40 bytes, and the structure isB
The size of the 48 bytes is 48 bytes. Why does such a difference occur? This is the role of memory alignment that we are going to discuss today.
Memory alignment concept
Memory alignment refers to a strategy in which the compiler adjusts the location of data in memory in order to optimize memory access speed. Different types of data have different alignment requirements in memory, such as:
-
int8
Variables of types are usually aligned to a 1-byte boundary. -
int32
Variables of types are usually aligned to a 4-byte boundary. - Pointer (such as
string
) is usually aligned to an 8-byte boundary.
To meet these alignment requirements, the compiler may insert some "fill" bytes between the fields of the structure, ensuring that each field is aligned correctly.
Structural memory layout analysis
Let's analyze in depthA
andB
Memory layout of two structures, and see how the compiler allocates memory for them.
Memory layout of structure A
| a (int8) | b (int8) | padding (2 bytes) | c (int32) | d (string, 8 bytes) | e (string, 8 bytes) |
-
a
andb
yesint8
Type, each accounting for 1 byte. -
c
yesint32
Type, 4 bytes need to be aligned,b
There will be 2 padding bytes afterwards. -
d
ande
yesstring
Type, each accounting for 8 bytes.
Total size is: 1 + 1 + 2 + 4 + 8 + 8 = 24 bytes.
Memory layout of structure B
| a (int8) | padding (7 bytes) | e (string, 8 bytes) | c (int32) | padding (4 bytes) | b (int8) | padding (3 bytes) | d (string, 8 bytes) |
-
a
yesint8
Type, occupies 1 byte, followed by 7 padding bytes, soe
Ability to align to an 8-byte boundary. -
c
yesint32
Type, requires 4 byte alignment, so inc
There is no fill afterwards. -
b
yesint8
Type, need to be filled with 3 bytes to align tod
8 byte boundary of .
Total size is: 1 + 7 + 8 + 4 + 4 + 1 + 3 + 8 = 36 bytes.
Please noteThe Go compiler mayd
ande
Treated as an 8-byte alignment type (depending on system and compiler implementation), so the total size may be 48 bytes.
How to optimize the memory layout of the structure
In order to reduce the memory usage of the structure, we can rearrange the fields according to the alignment requirements of the fields. For example:
Declare the large field first (such asstring
andint32
), followed by small fields (such asint8
) can reduce the padded bytes in memory.
We canB
The structure is changed to the following form:
type OptimizedB struct { e string d string c int32 a int8 b int8 }
This reduces memory padding, thereby optimizing memory footprint.
Summarize
Memory alignment is an important strategy for compilers to optimize memory access speed. While it may have a small impact on most applications, understanding and optimizing memory alignment can lead to significant performance gains in high-performance scenarios or memory-constrained environments.
In Go language, understanding the memory alignment rules of structures and rationally arranging the field order of structures can not only improve the performance of the program, but also reduce memory waste. This is a simple and effective optimization method, and I hope everyone can flexibly use it in future programming practices.
This is the article about exploring memory alignment in Go language. For more related Go memory alignment content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!