Updated 31 January 2022
Here is again an interesting article on the memory layout in swift.
Ever wondered how the memory is structured when we create any object in swift?
In this article, you will get to know the basics of a memory structure in swift.
Firstly, we will get to know some fundamental concepts of the memory layout.
So let’s begin with the tutorial
Memory is a bunch of binary digits that are simply called bits.
If we group the bits into groups of 8, then we can call this new unit byte. 8-bits size is the number of bytes that contain a type in memory.
Size is the number of bytes is required to hold a type in memory.
Alignment is the way data is arranged and accessed.
Stride is the number of bytes between two elements. It tells you how far apart each element of the type is located in the memory.
enum MemoryLayout<T>
MemoryLayout enumeration gives the size, stride, and alignment of the type in the memory.
Any data type’s stride is always greater than or equal to a size of the same type.
You can check these values for any data type as below.
1 2 3 |
print(MemoryLayout<Int>.size) print(MemoryLayout<Int>.alignment) print(MemoryLayout<Int>.stride) |
As, Integer takes 8 bytes of memory in Swift, similarly for Boolean and other data types you can check the memory layout.
Alignment is something like how much memory is needed to store values in memory, size is the number of bytes needed to store the type usually the sum of all the size of the types, stride represents the distance between two elements in the memory.
1 2 3 4 5 6 7 8 |
struct MemoryExample { var a: Int var b: Bool } print(MemoryLayout<MemoryExample>.size) // prints 9 print(MemoryLayout<MemoryExample>.stride) // prints 16 print(MemoryLayout<MemoryExample>.alignment) // prints 8 |
In Swift, when working with the compound data types, alignment is equal to the maximum size of the property for example 8 bytes in the above example as Integer has 8 bytes of size.
In addition, size will be the sum of all the properties of the compound data type(MemoryExample) that is 8 bytes + 1 bytes. Stride will be calculated by rounding up to the next multiple of the alignment which is 16 in this case.
Let us consider another example just by making the variable b of boolean type as the first property and then declaring the variable a of integer type.
1 2 3 4 5 6 7 8 9 |
struct MemoryExample { var b: Bool var a: Int } print(MemoryLayout<MemoryExample>.size) // prints 16 print(MemoryLayout<MemoryExample>.stride) // prints 16 print(MemoryLayout<MemoryExample>.alignment) // prints 8 |
Now, the size has been increased but how?
Here, 1 byte for the boolean is placed first and then the buffer of 7 bytes is taken after that 8 bytes of memory is used to store the integer value, hence maintaining the alignment of 8 bytes. This makes the stride to 16 bytes as the new type will be stored after 16 bytes.
Till now we checked the memory layout for the value types such as struct, now we will be checking the memory layout for the class which is reference types.
Consider below example
1 2 3 4 5 6 7 8 |
class MemoryExample { var a: Bool = true var b: Int = 10 } print(MemoryLayout<MemoryExample>.size) // prints 8 print(MemoryLayout<MemoryExample>.stride) // prints 8 print(MemoryLayout<MemoryExample>.alignment) //prints 8 |
Everything is 8 bytes as class is a reference rather than an object and all references are 8 bytes, so everything is 8 bytes.
In conclusion, stored properties are basically value types such as struct and classes are reference types.
That’s why struct uses stack data structure and classes use heap data structure.
Here is what Apple’s official documentation says on memory layout.
Please read out more interesting articles here.
If you have more details or questions, you can reply to the received confirmation email.
Back to Home
Be the first to comment.