美文网首页
内存对齐探上一探

内存对齐探上一探

作者: 灰溜溜的小王子 | 来源:发表于2020-09-10 23:33 被阅读0次

写在前面:

  • 在了解内存对齐之前先了解一下各数据类型在内存中的大小,目前我们比较常用的是64位系统,所以我们的研究对象统一采用64位的大小作为参考。
    image.png

了解下lldb调试命令:

po                 打印信息
p                 打印详细的信息
bt                 打出堆
register read      读取寄存器
x                  读取内存段
x/4gx              读取4段内存段

说到内存对齐这个玩意儿,说实话一脸懵逼
光这个三个玩意儿(如何获取内存的大小)够喝一壶:

1.sizeof()
2.class_getInstanceSize()
3.malloc_size()
一块看看是个啥吧,创建一个类,属性如下
@interface PHPerson : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *nickName;
@property (nonatomic, assign) int age;
@property (nonatomic, assign) long height;
@end
  • 导入头文件
· #import <objc/runtime.h>
· #import <malloc/malloc.h>
  • 打印结果


    打印结果
    分配情况一

我的理解是(个人理解有待验证):
sizeof:是person这个指针所isa需要的内存大小8字节固定
class_getInstanceSize:存储这个PHPerson类所需要的空间大小
malloc_size:系统分配的空间大小(内存对齐原则16字节)
为了验证咱的猜测,添加断点

  • Xcode查看内存地址:Debug->Debug Workflow->view memory


    image.png

    iOS是小端模式,需要倒着读数据.(详解大端模式和小端模式)

    • 大端模式:是指数据的高字节保存在内存的低地址中,而低子节数据保存在内存的高地址中。
    • 小端模式:是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中。
注释掉heigh类型为long的属性之后打印如图: image.png
分配情况二

注释掉所有属性之后


image
分配情况三 属性占用字节数

这下懵了:

size_t instanceSize(size_t extraBytes) const {
        if (fastpath(cache.hasFastInstanceSize(extraBytes))) {
            return cache.fastInstanceSize(extraBytes);
        }

        size_t size = alignedInstanceSize() + extraBytes;
        // CF requires all objects be at least 16 bytes.
        if (size < 16) size = 16;//看见没有这是重点额,不够十六字节就分配十六个字节大小
        return size;
    }

注意:NSObject对象内部只使用了8个字节的空间(可以通过class_getInstanceSize函数获得)

class_getInstanceSize(Class _Nullable cls) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);


size_t class_getInstanceSize(Class cls)
{
    if (!cls) return 0;
    return cls->alignedInstanceSize();
}

 uint32_t alignedInstanceSize() const {
        return word_align(unalignedInstanceSize());
    }

#ifdef __LP64__
#   define WORD_SHIFT 3UL
#   define WORD_MASK 7UL
#   define WORD_BITS 64
#else
#   define WORD_SHIFT 2UL
#   define WORD_MASK 3UL
#   define WORD_BITS 32
#endif

static inline uint32_t word_align(uint32_t x) {
//此时WORD_MASK是64位下的WORD_MASK 7UL 即8字节对齐
    return (x + WORD_MASK) & ~WORD_MASK;
}

通过一个例子先了解下字节对齐,下边再探

struct object {
    int a; // 4
    NSString *b; // 8
    int c; // 4
    char d; // 1
};
  • 未对齐 - 对齐

打开PHPerson.h中所有属性变为成员变量方便分析,此时cd到当前工程目录下通过xcrun -sdk iphonesimulator clang -rewrite-objc main.mmain.m编译成cpp的c++文件如图

image.png
@interface PHPerson : NSObject{
    NSString *name;
    NSString *nickName;
    int age;
    long height;
}

编译后可以看到PHPerson对象其实是个结构体指针,内存对齐可以参考上方结构体object


struct PHPerson_IMPL {
      //指针对象,占用8字节
    struct NSObject_IMPL NSObject_IVARS;
    NSString *name;//字节8                         0-7
    NSString *nickName;//8字节                   8-15
    int age;//4字节                             16-20  补齐21-23
    long height;//8字节                        24-31
};  共需要8+32  字节数
  • 发现PHPerson结构体中自动增加了一个成员变量NSObject_IVARS,即Class类型的成员变量。于是,获取PHPerson实例对象的内存大小,就等价于获取PHPersonl_IMPL结构体所占用的内存大小。

  • 在上述的讲解中,可以知道获取内存大小方法的区别。malloc_size函数获取系统分配的内存大小,class_getInstanceSize是获取实际占用的内存大小。

  • 通过上述打印结果可以看出,系统分配给PHPerson实例对象内存是48个字节,实际占用的也是40个字节。看到这,想必疑问重重,实际占用的内存大小不应该是8 + 8 + 4 + 8 = 28个字节么?这是怎么回事呢?

  • 其实这里涉及一点计算机的知识点——内存对齐。在结构体中,总大小为结构体对最大成员大小的整数倍,如不满足,最后填充字节以满足,可分配的最小内存是结构体中内存占用最大的成员变量的大小。

  • PHPerson_IMPL结构体中,占用内存最大的成员变量是NSObject_IVARS,name,nickName,height,占用的内存是32个字节。成员变量_age占用4个字节,由于不满足内存对齐规则,故实际占用8个字节,实际占用的内存大小就是40个字节。

参照:关于NSObject对象的内存布局

相关文章

  • 内存对齐探上一探

    写在前面: 在了解内存对齐之前先了解一下各数据类型在内存中的大小,目前我们比较常用的是64位系统,所以我们的研究对...

  • 004-iOS 内存对齐

    一、概念 内存对齐是编译器为每个数据元单位安排在适当的内存位置上。 二、内存对齐原因 为了访问未对齐的内存,处理器...

  • 2.iOS底层学习之内存对齐

    学习了内存对齐之后的疑问?? 1.为啥要内存对齐?2.内存对齐的规则?3.内存对齐实例分析。 内存对齐的目的 上网...

  • 内存对齐

    本次主要讨论三个问题: 什么是内存对齐 内存对齐的好处 如何对齐 内存对齐 内存对齐是一种提高内存访问速度的策略。...

  • 结构体内存对齐

    对象内存对齐 探讨的问题 1.什么是内存对齐?2.为什么要做内存对齐?3.结构体内存对齐规则4.源码内存对齐算法 ...

  • 内存对齐

    为什么内存对齐计算机平台往往为了提高内存萃取效率,往往对数据进行对齐存放,如果不对数据存放进行对齐,会在存取效率上...

  • 内存对齐

    内存对齐 什么叫内存对齐内存对齐就是按照特定的规则对数据进行存储,一般编译器按照8字节对齐标准处理。内存对齐一般用...

  • iOS内存对齐

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

  • iOS 开发 内存对齐(练习)

    目录 内存对齐规则 对齐系数 面试题演练 一、内存对齐规则 (关于面试题中结构体内存对齐计算总结) 1.1、数据成...

  • OC底层原理三:内存对齐分析

    获取内存大小 上一篇我们简单的提了下内存字节对齐以及为什么要内存字节对齐,那么我们首先看下有什么方式可以获取内存大...

网友评论

      本文标题:内存对齐探上一探

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