首先,从最熟悉的入手 - 对象,看看这三个对象的内容,内存地址和指针地址。

LGPerson *p1 = [LGPerson alloc];
    LGPerson *p2 = [p1 init];
    LGPerson *p3 = [p1 init];
    LGNSLog(@"%@ - %p - %p",p1,p1,&p1);
    LGNSLog(@"%@ - %p - %p",p2,p2,&p2);
    LGNSLog(@"%@ - %p - %p",p3,p3,&p3);

输出结果:

可以看出3个对象指向的是同一个内存空间,所以其内容内存地址相同的,但是对象的指针地址是不同的。

alloc 的流程

callAlloc做了一个编译优化

计算所需开辟内存的大小流程

内存字节对齐原则

在解释为什么需要16字节对齐之前,首先需要了解内存字节对齐的原则,主要有以下三点

    数据成员对齐规则:struct 或者 union 的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如数据、结构体等)的整数倍开始(例如int在32位机中是4字节,则要从4的整数倍地址开始存储)
    数据成员为结构体:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储(例如:struct a里面存有struct b,b里面有char、int、double等元素,则b应该从8的整数倍开始存储)
    结构体的整体对齐规则:结构体的总大小,即sizeof的结果,必须是其内部做大成员的整数倍,不足的要补齐

为什么需要16字节对齐

需要字节对齐的原因,有以下几点:

    通常内存是由一个个字节组成的,cpu在存取数据时,并不是以字节为单位存储,而是以块为单位存取,块的大小为内存存取力度。频繁存取字节未对齐的数据,会极大降低cpu的性能,所以可以通过减少存取次数来降低cpu的开销
    16字节对齐,是由于在一个对象中,第一个属性isa占8字节,当然一个对象肯定还有其他属性,当无属性时,会预留8字节,即16字节对齐,如果不预留,相当于这个对象的isa和其他对象的isa紧挨着,容易造成访问混乱
    16字节对齐后,可以加快CPU读取速度,同时使访问更安全,不会产生访问混乱的情况

字节对齐-总结

    在字节对齐算法中,对齐的主要是对象,而对象的本质则是一个 struct objc_object的结构体,
    结构体在内存中是连续存放的,所以可以利用这点对结构体进行强转。
    苹果早期是8字节对齐,现在是16字节对齐
例如:
struct LGStruct1 {
    double a;   // 8 (0-7)
    char b;     // 1 [8 1] (8)
    int c;      // 4 [9 4] 9 10 11 (12 13 14 15)   /*9不是4的倍数,从4的倍数开始算起,占4个字节,就是(12,13,14,15)**/
    short d;    // 2 [16 2] (16 17)
}struct1;

// 内部需要的大小为: 17
// 最大属性 : 8
// 结构体整数倍: 24

iOS底层原理02-alloc源码分析的更多相关文章

  1. SpringMVC关于json、xml自动转换的原理研究[附带源码分析 --转

    SpringMVC关于json.xml自动转换的原理研究[附带源码分析] 原文地址:http://www.cnblogs.com/fangjian0423/p/springMVC-xml-json-c ...

  2. 65、Spark Streaming:数据接收原理剖析与源码分析

    一.数据接收原理 二.源码分析 入口包org.apache.spark.streaming.receiver下ReceiverSupervisorImpl类的onStart()方法 ### overr ...

  3. ConcurrentHashMap底层实现原理(JDK1.8)源码分析

    ref:https://blog.csdn.net/xu768840497/article/details/79194701 http://www.cnblogs.com/leesf456/p/545 ...

  4. [Android实例] Scroll原理-附ScrollView源码分析

    想象一下你拿着放大镜贴很近的看一副巨大的清明上河图, 那放大镜里可以看到的内容是很有限的, 而随着放大镜的上下左右移动,就可以看到不同的内容了 android中手机屏幕就相当于这个放大镜, 而看到的内 ...

  5. [Android实例] Scroll原理-附ScrollView源码分析 (转载)

    想象一下你拿着放大镜贴很近的看一副巨大的清明上河图, 那放大镜里可以看到的内容是很有限的, 而随着放大镜的上下左右移动,就可以看到不同的内容了 android中手机屏幕就相当于这个放大镜, 而看到的内 ...

  6. 22、BlockManager原理剖析与源码分析

    一.原理 1.图解 Driver上,有BlockManagerMaster,它的功能,就是负责对各个节点上的BlockManager内部管理的数据的元数据进行维护, 比如Block的增删改等操作,都会 ...

  7. 21、Shuffle原理剖析与源码分析

    一.普通shuffle原理 1.图解 假设有一个节点上面运行了4个 ShuffleMapTask,然后这个节点上只有2个 cpu core.假如有另外一台节点,上面也运行了4个ResultTask,现 ...

  8. 20、Task原理剖析与源码分析

    一.Task原理 1.图解 二.源码分析 1. ###org.apache.spark.executor/Executor.scala /** * 从TaskRunner开始,来看Task的运行的工作 ...

  9. 17、stage划分算法原理及DAGScheduler源码分析

    一.stage划分算法原理 1.图解 二.DAGScheduler源码分析 1. ###org.apache.spark/SparkContext.scala // 调用SparkContext,之前 ...

  10. SpringMVC关于json、xml自动转换的原理研究[附带源码分析]

    目录 前言 现象 源码分析 实例讲解 关于配置 总结 参考资料 前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门blog:http://www.c ...

随机推荐

  1. sql server某列根据逗号转多行,其它字段不变

    效果: 语句代码: declare @moulds varchar(4000); set @moulds='55-480730-03,55-487780-01,,55-487780-02 '; dec ...

  2. list集合之流操作

    1.根据某一个实体字段进行去重(分组)操作 List<Object> list = objectList.stream().collect(Collectors.collectingAnd ...

  3. (app笔记)Appium如何开启、配置、启用

    1.安装adb 2.打开手机调试 3.连接手机 4.appium运行前,手机需要io.appium.uiautomator2.server 和 Appium Settings. 5.appium操作: ...

  4. js-惰性函数

    1. 需求:我们现在需要写一个 foo 函数,这个函数返回首次调用时的 Date 对象,注意是首次. 使用场景:当我们每次都需要进行条件判断,其实只需要判断一次,接下来的使用方式都不会发生改变的时候, ...

  5. 思科数据中心CCIE稳定PASS

    乾颐堂DC数据中心CCIE,在增加新题的情况下一次PASS! 目前笔试.lab都在过人,需要备考的同学联系乾颐堂,机时充足!

  6. uni-app学习笔记之----getCurrentPages()的使用

    1.判断是否是首页 如果得到数组元素只有一个,说明是首页 2.得到页面中的信息 得到数组中的第一个元素代表首页,最后一个元素代表当前页

  7. python APScheduler用法

    参考: https://blog.csdn.net/weixin_44799217/article/details/127353134 https://blog.csdn.net/weixin_428 ...

  8. Camstar代码:指定执行某函数

  9. 【键盘快捷键】Super键

    键盘快捷键 Super键 Windows/方框键.它有时也会被称为 Windows 键,徽标键或系统键 打开任务管理器 Ctrl+Shift+Esc

  10. SQL注入之延时注入(10)

    以下提供两种方式进行延时注入 GET /sqli/Less-10/?id=1"+and+sleep(5)--+ HTTP/1.1 Host: 192.168.245.146:6101 Use ...