在讨论结构体内存对齐原理之前,首要介绍下iOS中获取内存巨细的三种方法
获取内存巨细的三种方法
获取内存巨细的三种方法别离是: sizeof
,class_getInstanceSize
,malloc_size
sizeof
-
siz嵌套分类汇总的操作步骤eof
是一个操作符
,不是函数 - 咱们一般用
sizeof
核算内存巨细时,传入的首要政策是数据类型
,这个在编译器的编译阶段苹果手机
(即编译时)就会供认巨细而不是在运行时供认。 -
sizeof
终究得到的作用是该数据类型
占用空间的巨细
class_getInsios15tanc嵌套是什么意思eSize
这个方法是runtime
供给的api
,用于获取类的实例政策
所占用的内存巨细,并返回具体的字节数,其本质就是获取实例政策中成员变量的内存巨细
malloc_size
这个函数是获取体系实践分配的内存算法的有穷性是指巨细
能够经过下面代码的输出作用来验证咱们上面的说法
#import &l嵌套查询sql句子t;Foundation/Foundation.h>
#import "WJPerson.h"
#import <objc/run算法是什么time.h>
#import <malloc/malloc.源码本钱h>
int main(int argc, const cha源码之家r * argv[]) {
@autoreleasepool {
WJPerson *person = [[WJPerso算法规划与剖析n alloc] init];
NSLog(@"person政策类型占用的内存巨细:%lu",s苹果摊上新诉讼izeof(person));
NSLog(@"person政策实践占用的内存巨细:%lu"ios下载,class_getInstanceSize([person ciOSlass]苹果摊上新诉讼));
NSLog(@算法的时刻复杂度是指什么"person政策实践分配的内存巨细:%lu",malloc_size((__bridge const void*)算法的时刻复杂度是指什么(person)));
}
return 0;
}
以下是打印作用
总结
-
sizeof
:核算类型占用的内存巨细,其间能够放根柢数据类型、政策、指针
-
关于
int
这样的根柢数据而言,sizeof
获取的就是数据类型占用的内存巨细,不同的数据类型
所占用的内存巨细是不相同的
-
关于
WJPerioslauncher14安卓版son
界说的实例政策而言,其政策类型的本质就是一个结构体
(即 struct objc_object)的指针源码
,所以源码网站sizeof(person)
打印的是政策person
的指针
巨细,咱们知道一个指针的内存巨细是8
,所以si算法的五个特性zeof(per苹果官网son)
打印是8
。留意:这儿的8字节
与isa
指针一点联络都没有!!!) -
关于
指针
而言,sizeof
打印的就是8
,因为一个指针
的内存巨细是8
-
-
class_getInstanceSize
:核算政策实践占用
的内存巨细,这个需求依据类的特征
而改嵌套查询变,假如自界说类没有自界说特源码编辑器手机版下载色,仅仅仅仅承继自NSObject
,则类的实例政策实践占用源码编辑器编程猫下载
的内存巨细是8算法工程师,能够简嵌套查询sql句子略理解为8字节对齐 -
malloc_size
:核算政策实践分配
的内存巨细,这个是由体系完结的,嵌套能够从上面的打印作用看出,实践分配
的和实践占用
的内存巨细并不持平
结构体内存对齐
接下来,咱们首要界说两个结构体,苹果别离核算ios是什么意思他们的内存巨细,以此来引进今日的正题:结构体内存对齐原理
struct WJStruct1 {
double a;
char b;嵌套是什么意思
int c;
short d;
}struct1;
struct WJStruct2 {ios是什么意思
double a;
int b;
char c;
short d;
}struct2;
//核算 结构体占用的内存巨细
NSLog(@"%lu算法是什么-%lu",sizeof(struct1),sizeof(struct2));
从打印源码编辑器手机版下载作用咱们能够看出一个问ioslauncher题,两个结构体乍一看,没什么差嵌套结构异,其间界说的变量
和 变量类型
都是一致的,仅有的差异
仅仅在于界说变量的次序不一致
,那为什么他们占用的内存巨细不持平
呢?其实这就是iOS中的内存字节对齐
现象
内存对齐准则
能够将内存对齐准则
能够理解为以下ios14.4.1更新了什么几点:
- 【源码年代准则一】源码共享网 数据成员的对齐规矩能够理解为
min(m, n)
的公式, 其间m
标明当时成员的开始方位
,n
标明当时成员所需求的位数
。假如满意条件m
整除n
(即m % n苹果官网 == 0
),n
从m
方位开始存源码网站储, 反之继续检查m+1
能否整除n
,直到能够整除
, 从而就供认了当时成员的开始方位
。 - 【准则二】数据成员为结构体:当结构体
嵌套
了结构体时,作为数据成员的结构体的本身长度作为外部结构体的嵌套是什么意思最大成员的内存巨细,比方结构体a
嵌套结构体b
,b
中有char、int、double
等,则b的本身长度源码为8
- 【准则三】最后
结构体的内存巨细
有必要是结构体中最大成员内存巨细
的整数倍
,缺嵌套函数少的需求补齐。
验证对齐规矩
下表是各种数据类型
在iOS
中的占用内存巨细,依据对应类型来核算结构体中内存巨细
咱们能够经过下图来阐明下为什么两个结构体 WJStruct1
& WJStruct2
的内存巨细打印不一致的情况,如图所示
- 依据
内存对算法的五个特性齐规矩
得出WJStruct1
的苹果官网内存巨细是18
,但源码编辑器是18源码编辑器手机版下载
不是最大变量的字节数8
的整数倍,18
向上取整到24
,首要是因为24
是8
的整数倍,所以si苹果13zeof(struct1)
的作用是24
- 依据
内存对齐规矩
得出WJStruct2
的内存巨细是16
,16
刚好是8
的整数倍,所以源码网站sizeof(struct2)
的作用是16算法剖析的目的是
结构体嵌套ios最好玩的手游结构体
上面的两个结构体仅仅简略的界说数据成员,下面来一个比较复杂的,结构体中嵌套结构体的内存巨细核算情况
首要界说一苹果8个结构体WJStruct3,在WJStruct3中嵌套WJStruct1,如下所示
struct WJSt源码编辑器r算法的有穷性是指uct3 {
double a; //8
int b; //4
char c; //1
sh嵌套循环ort d; //2
int e; //4
struct WJStruct1 str; //24
}struct3;
//打印 WJStruct3 的内存巨细
NSLog(@苹果11"struct3内存巨细:%lu", sizeof(struct3));
NSLog(@算法的有穷性是指"struct3中结构体成员内存巨细:苹果11%lu", sizeof(struct3源码本钱.striOS));
依据ios14.4.1更新了什么内存对齐规矩
,咱们能够画WJStruct3
的内存分布图:
剖析WJStruct3
的内存核算:
-
变量a
:double类型
占8
个字节,从0
开始,此刻min(0,8)
,即0-7
存储a
-
变量b
:int类型
占4
个字节,从8
开始,此刻min(8,4)
,8
能够整除4
,即8-1源码本钱1
存储b
-
变量c
:char类型
占1
个字节,从12
开始,此刻min(12, 1)
,12
能够整除1
,即12
存储c
-
变量d
:short类型
占2
个字节,从1ioslauncher3
开始,此刻min(13,2)
,不能整除,+1
后能够整除,即14-15源码买卖网站源码
存储d
-
变量e
:int类型
占4
个字节,从16
开始,此刻min(16,4)
,16
能够整除4
即16-19
存储e
-
结构体成员str
:str
是一个结构体,依据内存对齐准则二
,结构体成员要从其内部最大成员巨细的整数倍开始存储,而WJSt苹果摊上新诉讼ruct2
中ios下载最大的源码之家成员巨细为8
,所源码买卖网站源码以str
要从8
的整数倍开始,当时是从20
开始,所以不契合要求,需求往后移动到24
,24
是8
的整数倍,契合内存对齐准则
,所以24-47
存储str
因此WJStruct3
的需求的内存巨细为 48
字节,而 WJStruct3
中最大变量为str
, 其最大成员内存字节数为8
,依据内存对齐准则,所以 WJStruct3
实践的内存巨细有必要是 8
的整数倍,48
正好是8
的整数倍,所以 sizeof(WJStruct3)
的作用是 48
内存优化(特征重排)
WJStruct1
经过内存字节对齐准则,添加了8
个字节源码编辑器手机版下载,而 WJStruct2
经过内存字节对齐准则,经过4+1+2
的组合,只需求补齐一个字节即可满意字节对齐规矩,这儿得出一个结论结构体内存巨细与结构体成员内存大ios模拟器小的次序有关
假如是结构体中数据成员
是依据内存从小到大
的次序界说的,依据内存对齐规矩
来核算结构源码编辑器编程猫下载体内存巨细,需求添加有较大源码年代的内存padding
即内存占位符,苹果11才华满意内存对齐规矩,比较糟蹋内存
假如是结构体中数据成员
是依据内存从大到小
的次序界说的,依据内存对齐规矩来核算结构体内存巨细,咱们只需求补齐少数内苹果电影存padding
即可满意堆存对齐规矩,这种方法就是苹果中选用的
,使用空间换时刻,算法的有穷性是指将类中的特征进行重排,来抵达优化内存的目的
以下面这个例子来进行阐明
苹果中特征重排
,即内存优化
- 界说一个自界说
WJPerson苹果手机
类,并界说几个特征
@interface WJPerson : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *nickName;
@property (nonatomic, assign) int age;
@property (nonatomic, assign) long hios14.4.1更新了什么eight;
@嵌套proios15perty (嵌套结构nonatomic) char c1;
@property (nonatomic) char c2;
@end
- 在
main
中创立WJPerson
的实例政策,并对其间的几个特征赋值
int main(int argc, const char * argv[]) {
@autoreleasepool {
WJPerson *person = [WJPerson all苹果手机oc];
person.name = @"Jem";
person.nick苹果电影Name = @"WJ";
person.age = 18;
person.c1 = 'a';
person.c2 = 'b';
NS源码之家Log(@"%@"ios是什么意思,person);
}
return 0;
}
- 断点调试
person
,依据WJP算法是什么erson
的政策地址,查找出特征的值
当咱们向经过0x0000001200006261
地址找出age嵌套是什么意思
等数据时,发苹果13现读源码编辑器编程猫不到,这儿无法找出值的原因是苹果中针对age、c1源码买卖网站源码、c2特征的内存进行源码本钱了重排,因为age
类型占4
个字节ios最好玩的手游,c源码本钱1
和c2
类型char
别离占1
个字节,经过4+1+1
的方法,按照8
字节对齐,缺少补齐的方法存储在同一块内存中,
-
age
的读取经过po 0x00000012
(18) -
c1
的读取经过x/c 0x61
(a) -
c2
的读取经过x/c 0x62
(b)
总结
所以,这儿能够总结下苹果源码共享网中的内存对齐
思维:
-
大部分的内存都是经过固定的内存块进行读取,
-
虽然咱们在内存中选用了内存对齐的方法,但并不是一切的内存都能够进行糟蹋的,苹果会自动对
特征进行重排
,以此来优化内存
-
字节对齐终究选用多少字节对齐?咱们能够经过
obj源码编辑器编程猫下载c4
的源码来进行剖析-
class_getInstanceSize
:是选用苹果手机8
字节对齐,参照的政策的特征内存巨细 -
malloc_size
:选用16
字节对齐,参照的整个政策的内存巨细,政策实践分配的内存源码年代巨细有必要是1ioslauncher14安卓版6
的整数倍
-
-
内存对齐算法原理:
k + 15 >> 4 << 4
,其间右移4
+左移4
相当于将后4
位抹零,跟k/16 * 16
相同 ,是16
字节对齐算法,小于16
就成0
了.