美文网首页
OC底层原理02—内存对齐

OC底层原理02—内存对齐

作者: 夏天的枫_ | 来源:发表于2020-09-09 19:34 被阅读0次

为什么要内存对齐?

  • 1.性能方面:提升CPU读取速度。CPU是按照块来读取的,块的大小可以为2,4,8,16。块的大小也称为内存读取粒度。假设某平台硬件CPU读取粒度为8,如果没有内存对齐:
    1)CPU从0-7读取数据,正常取出;
    2)如果数据从第2字节开始,CPU先读取0-7,再读取8-15字节的数据,然后将2-10字节的数据组合为正确的数据返回。
    这样就导致CPU进行了两次读取,效率很低。如果是数据的内存是对齐,CPU可一次性的读取出数据,虽然数据占用多余的内存空间导致一些内存碎片化,但是通过内存空间换取速度的方式是非常可取的。现在的手机、电脑也是通过扩容内存来换取读写速率的提升。
  • 2.平台硬件:不同的硬件平台对任意地址的数据读取不一,不是所有的硬件平台都可以访问任意地址上的任意数据,某些硬件平台只能在某些地址处取某些类型的数据,否则抛出硬件异常。

内存对齐原理

万物都有规则,内存对齐也有其规则:
NO.1:数据成员对⻬规则。结构(struct)(或联合(union))的数据成员,第
⼀个数据成员放在offset为0的地⽅,以后每个数据成员存储的起始位置要
从该成员⼤⼩或者成员的⼦成员⼤⼩(只要该成员有⼦成员,⽐如说是数组,结构体等)的整数倍开始(⽐如int为4字节,则要从4的整数倍地址开始存储。
NO.2:结构体作为成员。如果⼀个结构⾥有某些结构体成员,则结构体成员要从其内部最⼤元素⼤⼩的整数倍地址开始存储。(若struct a⾥存有struct b,b⾥有char,int ,double等元素,那b应该从8的整数倍开始存储.)
NO.3:结构体的总⼤⼩(sizeof的结果)必须是其内部最⼤成员的整数倍。不⾜的要补⻬。
现在来看看结构体内存的计算和对齐:
假设有两个结构体

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

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

其中结构体指针长度为8,结构体的内存尺寸则是其内部属性的集合。
sizeof(structOne) = 16;sizeof(structTwo) = 24
结果有点小惊喜和意外,都是一样的成员,因为排序不一样,其内存大小也不同。这是系统按照内存对齐做了“优化”的结果。
对照对齐规则:

structOne的字节分析

上图中是对structOne所占字节分析,该类型占用大小为[0,14],安卓内存对齐原则,其类型所需要的内存大小为最大成员字节大小的整数倍,故而16满足0-14的内存需求。
同理可得sizeof(structTwo)的内存所占位[0,18],共19个长度,安装规则其需求为24字节。

structTwo的字节分析

如果一个结构体嵌套了structOne组成了,按照规则structOne将为structThree中最大的内存成员,其中structOne中最大成员为double类型字节数为8,structThree实际所要的内存空间分别为:
int b; -> [0,1,2,3],
double a; -> 4,5,6,7,[8,9,10,11],
struct StructOne one; -> 12,13,14,15,[16,17...30,31]
共占用32个字节,
最大成员内存8的最小整数倍为32,所要structThree的内存空间大小为32。

struct StructThree{
  int    a; // 4字节
  double b; // 8字节
  struct StructOne one; // 16
}structThree;

拓展:内存计算

定义一个Book类,有以下属性,并在VC中实例化它。

// Book.h
@interface Book : NSObject

@property (nonatomic,copy) NSString * bookName;

@property (nonatomic,copy) NSString * bookAuth;

@property (nonatomic,assign) float  bookVersion;

@property (nonatomic,assign) int  pageNnumbers;

@end
   // 在VC中调用
   Book * book = [[Book alloc] init];
   book.bookName = @"Objective-C Programming";
   book.pageNnumbers = 256;
  
   NSLog(@"\nbook:%@ \nsizeof: %lu \nclass_getInstanceSize:%lu \nmalloc_size: %lu",book,sizeof(book),class_getInstanceSize([book class]),malloc_size((__bridge const void *)(book)));

执行会得到

2020-09-09 17:48:23 OC_MemoryAlignment[44017:1549093] 
book:<Book: 0x600000652a80> 
sizeof: 8 
class_getInstanceSize: 32 
malloc_size: 32
  • sizeof:是一个运算符,计算的是括号中类型占用内存的大小。此例中book为一个指针类型,故而大小为8;
  • class_getInstanceSize:源码如下:
/** 
 * Returns the size of instances of a class.
 * 
 * @param cls A class object.
 * 
 * @return The size in bytes of instances of the class \e cls, or \c 0 if \e cls is \c Nil.
 */
OBJC_EXPORT size_t
class_getInstanceSize(Class _Nullable cls) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

它是runtime中的一个方法,获取的是类实例实际占用内存大小(字节单位)。Book中定义了4个属性,class_getInstanceSize计算就是Book类实例四个属性实际占用内存大小为32字节。(1个属性对应8个字节大小)

  • malloc_size源码中这样写道:
extern size_t malloc_size(const void *ptr);
    /* Returns size of given ptr */

它返回的则是实际类实例开辟的内存空间大小。

总结
sizeof-> 类型占用内存的大小
class_getInstanceSize -> 实际占用内存大小(字节单位)。
malloc_size->实际开辟的内存空间大小。

各类型所占内存空间


相关文章

  • iOS--OC底层原理文章汇总

    OC底层原理01—alloc + init + new原理OC底层原理02—内存对齐OC底层原理03— isa探究...

  • OC底层原理汇总

    OC底层原理(一).alloc实际调用流程分析OC底层原理(二).内存分配与内存对齐OC底层原理(三)、isa、对...

  • OC底层原理02—内存对齐

    为什么要内存对齐? 1.性能方面:提升CPU读取速度。CPU是按照块来读取的,块的大小可以为2,4,8,16。块的...

  • OC底层原理--内存对齐

    既然是底层原理系列,内存肯定是我们绕不过的一个知识点,今天这篇文章主要是通过源码来探索下OC底层是怎么进行内存对齐...

  • OC底层原理-内存对齐

    在探讨内存对齐原理之前,首先介绍下iOS中获取内存大小的三种方式 获取内存大小的三种方式 获取内存大小的三种方式分...

  • OC底层02:内存对齐

    什么是内存对齐 先来看一个例子 每种数据类型的大小可参考: 按照图计算,内存大小应该都为 ,然后运行结果如图: 可...

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

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

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

    在探讨内存对齐原理之前,首先介绍下iOS中获取内存大小的三种方式 获取内存大小的三种方式 获取内存大小的三种方式分...

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

    OC底层原理 学习大纲 前期准备 1.lldb打印规则 po: 对象信息 p: 对象信息 x: memory r...

  • OC底层原理04 - 内存对齐

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

网友评论

      本文标题:OC底层原理02—内存对齐

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