美文网首页
iOS 内存对齐探究

iOS 内存对齐探究

作者: qinghan | 来源:发表于2021-06-08 18:45 被阅读0次

影响OC对象内存大小的因素

数据类型内存大小:


占用大小.png

代码分析

@interface QHPerson : NSObject

{
    //isa 8
    NSString *level; //8
}
@property (nonatomic, copy) NSString *name; //8
@property (nonatomic, copy) NSString *nickName; //8
@property (nonatomic, assign) int age; //4
@property (nonatomic, assign) long height; //8
@end

QHPerson *p = [[QHPerson alloc] init];
p.name = @"qinhan";
p.age = 18;
size_t instansSize =  class_getInstanceSize([QHPerson class]);
NSLog(@"instansSize :%lu",instansSize);

通过class_getInstanceSize获取实例的大小,

打印结果.png
根据我上面标注的结果是44,为什么打印结果是48内,实际上在alloc的时候苹果做了8字节的对齐处理,参考上篇文章
控制变量,我们添加个方法
添加方法.png
发现内存大小不变
减少成员变量或属性
注释成员变量.png
打印结果:
打印.png
发现内存大小变小
总结:对象分配的内存大小成员变量属性有关

OC对象内存分析

内存分析.png
然后我们去掉char1这个变量
内存分析.png
  • 可以看到第三段内存的变化0x0000001200000063,第二次0x0000000000000012,两次int所占的字节不一样,由此可见底层做了字节对齐的优化处理。
  • x/8gx p 是lldb简写指令,下面附上一张别人总结的,以便理解
    LLDB文档.png

pragma pack(show)

  • pragma pack(show) 的大致作用就是改变编译器的对齐方式,如果不设置默认是8,我们也可以通过show的置来改变。
  • 最终的对齐方式还是要取变量所占的字节对比,取更小的,min(a,show). 比如int是4字节,默认是8 ,该成员就会以4字节对齐。
    截屏2021-06-09 上午10.02.27.png

内存对齐原则

数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储。这个整数应该是编译器设置的值和成员类型的值中的小值。

2.当结构体嵌套了结构体时,作为数据成员的结构体的自身长度取内部结构体的最大成员的内存大小,比如结构体a嵌套结构体bb中有charintdouble等,去最大的作为b的自身长度为,这里取double类型为8,这个8也要于编译器设置的值进行对比,如果show = 4,那么应该去4.
3.结构体的内存大小必须是结构体最大成员内存大小的整数倍,不足的需要补齐

规则验证

下面定义了两个结构体来验证一下内存的大小

struct QHStruct1{
    char a;     //1字节
    double b;   //8字节
    int c;      //4字节
    short d;    //2字节
}QHStruct1;
struct QHStruct2{
    double b;   //8字节
    int c;      //4字节
    short d;    //2字节
    char a;     //1字节
}QHStruct2;

查看打印结果

打印结果.png
纳尼,打印结果不一样,同样的成员顺序不一样打印结果居然不一样。但是如果我们了解内存对齐规则,就不会这么认为了
通过上面的对齐规则,通过图表的形式展现了,
QHStruct1和```QHStruct2``的内存分布,与打印结果一致
结构体内存分布.png

计算结构体QHStruct1 内存大小详细流程

变量a:占1个字节,从0开始,此时min(0,1),即 0存储 a
变量b:占8个字节,从1开始,此时min(1,8)1不能整除8,继续往后移动,知道min(8,8),从8开始,即8-15 存储b
变量c:占4个字节,从16开始,此时min(16,4)16可以整除4,即 16-19 存储 c
变量d:占2个字节,从20开始,此时min(20, 2)20可以整除2,即20-21 存储 d

计算结构体QHStruct2 内存大小详细流程

变量b:占8个字节,从0开始,此时min(0,8),即0-7 存储b
变量c:占4个字节,从8开始,此时min(8,4)8可以整除4,即 8-11 存储c
变量d:占2个字节,从12开始,此时min(12, 2)12可以整除2,即12-13存储 d
变量a:占1个字节,从14开始,此时min(14,1),即 14存储a

结构体嵌套
struct QHStruct2{
    double b;   //8字节
    int c;      //4字节
    short d;    //2字节
    char a;     //1字节
}QHStruct2;

struct QHstruct3{
    double b;   //8字节 0-7
    int c;      //4字节 8 9 10 11
    short d;    //2字节 12 13
    char a;     //1字节 14
    struct QHStruct2 str; //
    
}QHstruct3;

其实嵌套后和没有嵌套逻辑一样,只不过这里的str要按照成员里面最大的字节8来计算,相当于n =8, 这样就很容易算出,结构体从16出开始放,这样就是16+16=32字节

计算内存大小的几个方法

class_getInstanceSize
sizeof
malloc_size
举个例子

- (void)test1
{
    QHPerson *p = [[QHPerson alloc] init];
    
    p.name = @"qinhan";
    p.age = 18;
    p.nickName = @"123";
    //p.height = 180;
    p->level = @"青铜";
   // p.char1 = 'c';
    
    size_t instansSize =  class_getInstanceSize([QHPerson class]);
    NSLog(@"sizeOf :%lu",sizeof(p));
    NSLog(@"instansSize :%lu",instansSize);
    NSLog(@"objc对象实际分配的内存大小:%lu",malloc_size((__bridge const void*)(p)));
}

打印结果


截屏2021-06-08 下午6.36.07.png

发现instansSize 计算的大小和malloc_size计算大小不一样,
这是因为instansSize8字节对齐,也就是是8的倍数
imalloc_size16字节对齐,也就是16的倍数

内存优化

通过上面结构体内存对齐以及上面的内存分析,发现属性的顺序不一样,内存大小不一样,所以苹果底层做了一些优化.用空间换时间,将类中的属性进行重排,以此来达到内存优化的目的

相关文章

  • iOS 内存对齐探究

    影响OC对象内存大小的因素 数据类型内存大小: 代码分析 通过class_getInstanceSize获取实例的...

  • iOS底层探究 - 内存对齐

    目录1:内存对齐的原因2:内存对齐的规则3:结构体内存分配演练以及在iOS中对象成员的内存分配探索 一 :内存对齐...

  • 002-OC对象原理探究 - 结构体内存对齐

    引言 上一篇文章,探究 alloc的过程中,提到内存对齐。下面我们通过对OC对象QLPerson探究来展开内存对齐...

  • 探究内存对齐

    什么是内存对齐 现代计算机中内存空间都是按照 byte 划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址...

  • iOS底层探究-05:内存对齐

    获取内存大小的三种方式 sizeof class_getInstanceSize malloc_size size...

  • iOS对象原理探究:内存对齐

    在开始之前,我们先了解下接下来会用到的 lldb 调试指令: 接下来,我们还是先举个栗子?。 Person 栗子?...

  • OC底层原理 05: 内存对齐原理

    主动已经是我对热爱东西表达的极限了 通过对结构体内存是如何对齐的?打开内存对齐原理的大门。 在探究内存对齐之前,先...

  • iOS内存对齐

    这篇文章我们来探索一下iOS内存对齐的原理,在探索完内存对齐原理之后,你就会明白内存对齐的好处。 在讲述内存对齐时...

  • 联合体和位域

    联合体和位域 在上一篇iOS中关于内存对齐的探究[https://www.jianshu.com/p/c913b5...

  • iOS中关于内存对齐的探究

    结构体内存对齐的三大原则 1、数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据...

网友评论

      本文标题:iOS 内存对齐探究

      本文链接:https://www.haomeiwen.com/subject/ksbdeltx.html