preface
In most of your work, you will be exposed to the concept of memory alignment, and what is memory alignment? Today I’m going to explore this mystery. Without further ado, let’s look at how objects are stored in memory.
First, we’ll go ahead and create a DMPerson class, instantiate an object and assign values to each of its properties
@interface DMPerson : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *nickName;
@property (nonatomic, assign) int age;
@property (nonatomic, assign) float height;
@property (nonatomic, assign) char flag;
@end
DMPerson *p1 = [[DMPerson alloc] init
p1.name = @"mantou";
p1.nickName = @"MT";
p1.age = 16;
p1.height = 195.3;
p1.flag = 'a';
Copy the code
Then let’s look at its storage in memory
The first column is the address of the object in memory, followed by the corresponding value. Using the same code above, let’s add a little bit of print to see how much memory the object we created is in, how much memory the object type has, how much memory the object at least needs, and how much memory the system actually allocated
NSLog(@"Object type memory size --%lu".sizeof(p1));
NSLog(@"Minimum memory size required for an object --% LU".class_getInstanceSize([p1 class]));
NSLog(@"System allocated memory size --% LU".malloc_size((__bridge const void *)(p1)));
Copy the code
The results are as follows
The result was something of a surprise to me: the amount of memory the object required was not the same as the amount of memory the system actually allocated. Let’s start with the conclusion:
- In THE C language,
sizeof()
Is an operator that determines the data type or the length of an expression.sizeof()
Evaluation of occurs at compile time, so it can be used as a constant expression. whilesizeof(p1)
Print isp1
The type of is the object, which is essentiallyStructure pointer
class_getInstanceSize
The printed result is the minimum memory size required for the object, which we created hereDMPerson
The class has a total of five properties, including twoNSString
1,int
1,float
1,char
Type. Plus the class itselfisa
I need 8 bytes, soDMPerson
Class needs at least 8+8+8+4+4+1 = 33 and then8-byte alignment
, so the printout is 40.malloc_size
The printed result is the actual memory allocated by the system, which we calculated earlierDMPerson
A class needs at least 40 bytes to be stored completely, and the actual allocation of a class in memory is16-byte alignment
So the final result is 48.
Memory alignment
In the previous exploration, we learned that different data types occupy different sizes in memory. Let’s first steal an image and see how many bytes each type occupies (pretend @cooci).
Let’s say we have an object that has a property of type double, a property of type bool, and an property of type int. According to the comparison in the table, we need a total of 8+4+1=13 bytes to store it. If we arrange it in order, it will look like the following
Each time we read the data, we need to change the size of the data we read. For example, we read 8 bytes firstdouble
“, and then in the read 8 bytes, found unsuccessful, read another 1 bytes, readbool
And then read 1 byte later, and found that it was not successful, and finally changed to read 4 bytes, which is very low efficiency, so the system did some optimization when storing data, which is what we calledMemory alignment
. It should actually be stored as shown in the following figure
Here’s another example:
struct LGStruct1 {
double a;
char b;
int c;
short d;
}struct1;
struct LGStruct2 {
double a;
int b;
char c;
short d;
}struct2;
NSLog(@"%lu-%lu".sizeof(struct1),sizeof(struct2));
Copy the code
If these two constructions contain exactly the same elements, will they sizeof print the same? Let’s see what happens:
2021- 06- 09 00:20:14.623807+0800 001- Memory alignment principle [9031:384474] 24- 16
Copy the code
It turns out that two constructs that contain exactly the same contents are not the same because of the order of the variables. So why? Because of memory alignment, certain principles need to be followed.
Principles of memory alignment
Data member alignment principle
: (struct
) Or in combination with (union
), the first data member is placed inoffset
for0
In the future, the starting position for each data member storage starts with an integer multiple of the size of that member or the size of its children (as long as that member has children, such as arrays, structures, etc.)int
for4
Byte, from4
Integer multiples of address start storage)Structure as a member
If a struct has some struct members, the struct members are stored starting at an address that is an integer multiple of the largest internal element size. (struct a
The entitiesstruct b
.b
Are there inchar
.int
.double
And so on, sob
Should be from8
Is an integer multiple of.- Finishing touches: the size of the structure, i.e
sizeof
The result of must be an integer multiple of its largest internal member, and any shortfall must be made up
Structure alignment (no nesting)
For example, how do these two structures store data in accordance with the memory alignment principle, as shown in the following figure
The final number of bytes is18
According to the last item of memory alignment principle, it needs to be completed as its internal maximum memberdouble a
What occupy a space8
Integer multiples of bytes, so phi is equal to phi24
Bytes.The final number of bytes is16
According to the last rule of memory alignment,16
Byte is its largest internal memberdouble a
What occupy a space8
Integer multiples of bytes, so phi is equal to phi16
Bytes.
Finally, we come to the same conclusion as the printed result above, indicating that the system does follow this principle for data storage
Structure alignment (structure nesting)
Let’s look at another example of struct nesting
struct LGStruct1 {
double a;
char b;
int c;
short d;
}struct1;
struct LGStruct3 {
double a;
int b;
char c;
short d;
int e;
struct LGStruct1 str;
}struct3;
NSLog(@"%lu".sizeof(struct3));
Copy the code
Again, let’s look at the system first
2021- 06- 09 00:44:54.039441+0800 001- Memory alignment principle [9380:400671] 48
Copy the code
And his specific storage ideas, as shown in the figure
Due to thestruct LGStruct1 str
Is also a structure, so it needs to be byte aligned internally, and finallystr
The number of bytes is24
Bytes. In accordance with theMemory alignment principle
Article 2,str
Need from24
Location to start storage occupancy24
Bytes. The number of bytes occupied is48
Bytes.
Here are two more examples
struct DMStruct1 {
double a;
char b;
int c;
short d;
}struct1;
struct DMStruct2 {
short a;
char b;
}struct2;
struct DMStruct3 {
double a;
int b;
char c;
short d;
int e;
struct DMStruct2 sss;
struct DMStruct1 str;
}struct3;
struct DMPerson4 {
double a;
int b;
char c;
short d;
int e;
struct DMStruct1 str;
struct DMStruct2 sss;
}struct4;
NSLog(@"%lu-%lu".sizeof(struct3),sizeof(struct4));
Copy the code
Their final memory distribution is shown in the following figure
The laststruct3
As a result of the48
Byte, andstruct4
As a result of the56
Bytes.
2021- 06- 09 02:24:50.797370+0800 001- Memory alignment principle [11167:486569] 48- 56
Copy the code
As you can see, structures within structures are also stored as a whole and need to be in-memory aligned.
At this point, we can conclude that for structures, the system does store data according to memory alignment principle. So we know that in iOS, objects are actually structures, so can we test that with the theory of structure alignment? Let’s move on
Memory optimization
Let’s modify the above code to change the location of the properties in DMPerson
@interface DMPerson : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) char flag;
@property (nonatomic, assign) int age;
@property (nonatomic, copy) NSString *nickName;
@property (nonatomic, assign) float height;
@end
Copy the code
Then continue printing as assigned above
The discovery is exactly the same as the previous output. And then we print each of them one by oneWe find that the system is actually right at the object levelMemory alignment
It’s optimized, no matter how your properties are arranged, the system will store the data in memory in the best order.
conclusion
The data storage of the system is aligned according to the principle of memory alignment. For structures, the order of members may cause a certain amount of memory space waste. For objects, the iOS system has helped us optimize the memory to ensure the optimal storage mode. Therefore, in the future development process, if the structure type is used, special attention should be paid to memory alignment issues.