当前位置: 首页 > news >正文

【iOS】内存对齐

内存对齐

OC基本数据类型所占字节数对比

在这里插入图片描述

注1BOOL在32位机器被定义为char、在64位机器被定义为bool
boolean_t在32位机器被定义为unsigned int、在64位机器被定义为int
NSInteger在32位机器被定义为int、在64位机器被定义为long
NSUInteger在32位机器被定义为unsigned int、在64位机器被定义为unsigned long
CGFloat在32位机器被定义为float、在64位机器被定义为double

以上多变的情况是是使用宏定义实现的,编译后可查看其实现

注2:由于C语言只会将bool的非0值置为1,因此,BOOL的使用过程中应注意在32位机器上并非只有1和0两种可能取值,取值范围是-128~127(其实也不用太在意,因为现在几乎没几个人还在用32位的手机)

内存对齐规则

  1. 数据成员对⻬规则
    结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int为4字节,则要从4的整数倍地址开始存储
  2. 结构体作为成员
    如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储,(struct a里存有struct b,b里有cha,int,double等元素,那b应该从8的整数倍开始存储)
  3. 收尾工作
    结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要补⻬

先有下面三个结构体:

struct Struct1 {double a;  // 8char b;    // 1int c;     // 4short d;   // 2
} struct1;struct Struct2 {double a;  // 8int b;     // 4char c;    // 1short d;   // 2
} struct2;struct Struct3 {double a;  // 8int b;     // 4char c;    // 1short d;   // 2int e;     // 4struct Struct1 struc;  // 24
} struct3;

根据上面的内存对齐规则,可计算出struct1所占用的字节数是24,struct2所占用的字节数是16,struct3所占用的字节数是48,通过sizeof也可以验证这些答案

内存对齐原因

性能
内存是以字节为基本单位,cpu在存取数据时,是以块为单位存取,并不是以字节为单位存取。频繁存取未对齐的数据(存取未对齐的数据可能开始在上一个内存块,结束在另一个内存块,中间可能要经过复杂运算在合并在一起,降低了效率),会极大降低cpu的性能。字节对齐后,会减低cpu的存取次数,提高了cpu的访问速率,这种以空间换时间的做法目的降低cpu的开销

跨平台
有些硬件平台并不能访问任意地址上的任意数据的,只能处理特定类型的数据,否则会导致硬件层级的错误。
有些CPU(如基于 Alpha,IA-64,MIPS,和 SuperH 体系的)拒绝读取未对齐数据。当一个程序要求这些 CPU 读取未对齐数据时,这时 CPU 会进入异常处理状态并且通知程序不能继续执行。
举个例子,在 ARM,MIPS,和 SH 硬件平台上,当操作系统被要求存取一个未对齐数据时会默认给应用程序抛出硬件异常。所以,如果编译器不进行内存对齐,那在很多平台的上的开发将难以进行。

OC对象内存对齐

在之前的文章中已经了解到OC对象实际上是结构体,结构体成员变量的内存排序遵循内存对齐规则,那么对象属性的内存排序也遵守内存对齐规则

创建一个Person类:

@interface Person : NSObject@property (nonatomic, assign)double a;
@property (nonatomic, assign)char b;
@property (nonatomic, assign)int c;
@property (nonatomic, assign)short d;@endPerson* person = [[Person alloc] init];
person.a = 7.7;
person.b = 's';
person.c = 7;
person.d = 7;
NSLog(@"%zd %zd", class_getInstanceSize([Person class]), malloc_size((__bridge const void *)(person)));  //  24 32

通过输出我们可以看出成员变量所占内存大小是24字节,其中isa要占8个字节,其余成员占16个字节,所以至少需要24字节
操作系统在分配内存时,也会有“内存对齐”,所以size是24,malloc_size返回 32,即系统实际分配内存32字节(从内存对齐的角度也可以算出32)

总结

内存对齐可以提高cpu的存取效率同时提升安全性,会有部分内存的浪费,但是系统又会根据数据存储情况进行内存优化,尽可能降低内存浪费,这样即保证了性能又减少了浪费

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Windows版MySQL5.7解压直用(如何卸载更换位置重新安装)
  • 六边形动态特效404单页HTML源码
  • C语言-网络编程-UDP通信创建流程
  • 大数据之数据抽取架构演变过程
  • 数据结构 —— B树
  • 【BUG】已解决:WslRegisterDistribution failed with error: 0x800701bc
  • Qt Style Sheets-使用样式表自定义 Qt 部件
  • Freedom of Choice
  • R语言模型评估网格搜索
  • Linux网络——套接字与UdpServer
  • Haproxy服务
  • 第四周:机器学习笔记
  • 接口测试JMeter-1.接口测试初识
  • 电磁兼容专栏说明
  • 深入浅出WebRTC—ALR
  • 【译】理解JavaScript:new 关键字
  • 【跃迁之路】【733天】程序员高效学习方法论探索系列(实验阶段490-2019.2.23)...
  • Android路由框架AnnoRouter:使用Java接口来定义路由跳转
  • javascript从右向左截取指定位数字符的3种方法
  • JSONP原理
  • JS函数式编程 数组部分风格 ES6版
  • php面试题 汇集2
  • 闭包--闭包作用之保存(一)
  • 关于 Cirru Editor 存储格式
  • 老板让我十分钟上手nx-admin
  • 利用DataURL技术在网页上显示图片
  • 手写双向链表LinkedList的几个常用功能
  • 网页视频流m3u8/ts视频下载
  • 一天一个设计模式之JS实现——适配器模式
  • 怎样选择前端框架
  • const的用法,特别是用在函数前面与后面的区别
  • 扩展资源服务器解决oauth2 性能瓶颈
  • #pragma once与条件编译
  • #多叉树深度遍历_结合深度学习的视频编码方法--帧内预测
  • (DFS + 剪枝)【洛谷P1731】 [NOI1999] 生日蛋糕
  • (Ruby)Ubuntu12.04安装Rails环境
  • (附源码)apringboot计算机专业大学生就业指南 毕业设计061355
  • (附源码)spring boot儿童教育管理系统 毕业设计 281442
  • (附源码)springboot码头作业管理系统 毕业设计 341654
  • (介绍与使用)物联网NodeMCUESP8266(ESP-12F)连接新版onenet mqtt协议实现上传数据(温湿度)和下发指令(控制LED灯)
  • (理论篇)httpmoudle和httphandler一览
  • (每日持续更新)jdk api之FileFilter基础、应用、实战
  • (免费领源码)Python#MySQL图书馆管理系统071718-计算机毕业设计项目选题推荐
  • (七)Knockout 创建自定义绑定
  • (最优化理论与方法)第二章最优化所需基础知识-第三节:重要凸集举例
  • .NET8使用VS2022打包Docker镜像
  • .NET正则基础之——正则委托
  • .NET中的十进制浮点类型,徐汇区网站设计
  • /usr/local/nginx/logs/nginx.pid failed (2: No such file or directory)
  • :如何用SQL脚本保存存储过程返回的结果集
  • @GlobalLock注解作用与原理解析
  • [ JavaScript ] JSON方法
  • [2021ICPC济南 L] Strange Series (Bell 数 多项式exp)
  • [ACM独立出版]2024年虚拟现实、图像和信号处理国际学术会议(ICVISP 2024)
  • [Algorithm][综合训练][kotori和气球][体操队形][二叉树中的最大路径和]详细讲解