Memory alignment of a struct in GO Lang
Image credits: https://medium.com/@go_26185

Memory alignment of a struct in GO Lang

Memory alignment is the practice of storing data at memory addresses that are multiples of the data size, enabling the CPU to access it efficiently in a single operation. It is the compiler's responsibility to align the data with respect to the machine's architecture.

In a 32-bit architecture machine, if we were to store 16-bits ( 2 byte ) followed by 32-bits ( 4 bytes ), the compiler would add a padding of ( 16-bits ) 2 bytes between 16-bits and 32-bits to satisfy the alignment ( The first byte of the data should be stored at a memory address which is a multiple of the size of the data ).

Offsetof in the examples below is the starting position of the variable relative to the struct in memory, and Sizeof gives the total number of bytes occupied by the struct. Padding is the number of bytes allocated to satisfy alignment.

Article content
Unordered fields
package main

import (
    "fmt"
    "unsafe"
)

type Something struct {
    a int8
    b int32
    c int8
}

func main() {

    something := Something{
        c: 1,
	b: 2,
	a: 3,
    }

    fmt.Println("Offset of a: ", unsafe.Offsetof(something.a)) // 0
    fmt.Println("Offset of b: ", unsafe.Offsetof(something.b)) // 4
    fmt.Println("Offset of c: ", unsafe.Offsetof(something.c)) // 8
    fmt.Println("Total size: ", unsafe.Sizeof(something)) // 12

}        

In the above example:

c int8 → 1 bytes, offset 0, takes 1 bytes, which is 0 itself.

b int32 → 4 bytes, offset 4, not 1 because 1 is not a multiple of 4, the closest multiple to 4 is 4. Occupies 4 bytes from that 4th position, so the next offset for the other variable is 8.

c int8 → 1 byte, offset 8, and 8 is a multiple of 1.        
a → 1 byte: [ 0 ]

pad 3 bytes: [1 - 3 ]

b → 4 bytes: [ 4 - 7 ]

c → 1 byte: [ 8 ]        

But the total should be 9 bytes, right? Well, the total size of the struct should indeed be a multiple of the highest byte-consuming field in the struct, which in our case is int32 ( 4 bytes ). 9 is not a multiple of 4; the next closest is 12. The compiler adds an extra padding of 3 bytes to the tail of the last field in the struct to make the next memory address a multiple of 4, which in our case is 12.


Field order matters:

Article content
Ordered fields
package main

import (
    "fmt"
    "unsafe"
)

type Something struct {
    b int32
    a int8
    c int8
}

func main() {

    something := Something{
        c: 1,
	b: 2,
	a: 3,
    }

    fmt.Println("Offset of a: ", unsafe.Offsetof(something.a)) // 4
    fmt.Println("Offset of b: ", unsafe.Offsetof(something.b)) // 0
    fmt.Println("Offset of c: ", unsafe.Offsetof(something.c)) // 5
    fmt.Println("Total size: ", unsafe.Sizeof(something)) // 8

}

        
b → 4 bytes: [ 0 - 3 ]

a → 1 byte: [ 4 ] ----> 4 is a multiple of 1

c → 1 byte: [ 5 ]

        

We have reduced the size to 8 bytes, but the struct still takes 8 bytes instead of 6 bytes because 5 is not a multiple of the highest byte-consuming field in the struct, which in our case is 4; the next closest address multiple of 4 is 8. Hence, the total size is 8.

So, with this knowledge, next time you write a program, do not forget to define a rule for your code assistant to order the fields for memory optimization.

“Keep exploring, keep coding, and stay curious!”

To view or add a comment, sign in

More articles by Rakesh Noothi

  • When Sharding Breaks: How Consistent Hashing Saves Your System

    The application you helped build is gaining popularity. On a quiet Saturday at the beach—your eyes on the orange sky…

  • Docker Networking Explained: How Containers Really Talk

    Docker networking allows containers to communicate with each other as well as with external applications. By default…

  • Intro to Kafka

    What is even APACHE KAFKA? Apache Kafka is an open-source distributed event streaming platform used to build real-time,…

  • Go Channels Explained: The Simple Way Goroutines Talk

    What are even channels? Channels in Go are like pipes that connect goroutines. They allow you to safely send and…

  • The HTTP

    Ever wondered how your browser fetches a webpage or how data flows between servers? Understanding HTTP is key to…

Others also viewed

Explore content categories