Runtime-OC对象的内存

作者: cyh老崔 | 来源:发表于2019-05-03 16:22 被阅读6次

一. NSObject对象分配内存大小

有两个方法可以得到一个指针对象的大小:

  • class_getInstanceSize(Class _Nullable cls): 得到编译器计算的大小, 即实际使用的大小
  • size_t malloc_size(const void *ptr): 得到实际分配的堆内存大小
#import <objc/runtime.h>
#include <malloc/malloc.h>

        NSObject *obj= [NSObject new];
        size_t size1 = class_getInstanceSize([NSObject class]);
        size_t size2 = malloc_size((__bridge void *)obj);
        NSLog(@"size1 = %zd, size2 = %zd", size1, size2);

输出:

size1 = 8, size2 = 16

可看到实际分配的堆内存大小>实际使用的内存大小
ref: https://forums.developer.apple.com/thread/114963

问题: oc为什么这样设计呢? 猜测:

  • 备用空间
  • 为什么是2倍? 正如方法缓存, 扩充时都是扩充一倍

二. 类对象组成

  1. 定义一个简单的类:
@interface Boy : NSObject
{
    @public
    int _weight;
}
@end

@implementation Boy
@end
  1. clang下:
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main-arm64.cpp

为什么指定生成cpp文件呢? 因为oc底层即cpp, 以免生成文件过大

生成文件中, 相关代码如下:

struct Boy_IMPL {
    
    struct NSObject_IMPL NSObject_IVARS;
    int _weight;
};
 struct NSObject_IMPL {
 Class isa;
 };

即类BoyBoy_IMPL 结构体, 而Boy_IMPL 结构体中包含下面两个成员变量:

Class isa; //每个对象都有的隐藏成员变量
int _weight; //其它定义的成员变量

2.1 体现在NSObject与Boy对象的内存大小如下:

size_t objSize = class_getInstanceSize(NSObject.class);
size_t boySize = class_getInstanceSize(boy.class);
NSLog(@"objSize: %zd, boySize: %zd", objSize, boySize);

输出:

objSize: 8, boySize: 16

可看到:

  • 一个空的NSObject对象, 就有8个字节, 即isa指针的大小
  • Boy对象的内存大小为16, 因为内存对齐, 所以Boy对象大小为8的倍数

2.2 体现在内存实际内容:

  • 查看内存地址:


    Boy对象地址
  • 地址对应内存:


    内存地址
  • arm是大端架构, 低位在高地址. 只查看自己的内存: 前16字节即可.

  • 前8个字节是isa指针

  • 后4个字节是0x42, 即66, 我们给_weight赋的值

  • 最后4个字节是内存对齐空余出来的4个字节, 并已经初始化为0

2.3 LLDB读取内存也可以看到这16字节的值

内存值

相关文章

  • Runtime-OC对象的内存

    一. NSObject对象分配内存大小 有两个方法可以得到一个指针对象的大小: class_getInstance...

  • JVM 常见内容汇总

    面试题 对象 对象的创建 分配内存 对象头 内存溢出 内存溢出与内存泄漏 内存溢出:系统无法再分配内存空间。 内存...

  • Java对象内存分析

    此处对象内存分析只针对Java基本对象,暂不对集合对象进行剖析。 内存 栈内存 堆内存

  • java 基础2

    1 java内存泄漏的几种情景 内存泄漏内存泄露是指无用对象(不再使用的对象)持续占有内存或无用对象的内存得不到及...

  • 面向对象

    面向过程与面向对象: 内存解析 对象数组的内存解析 匿名对象

  • 内存分配与回收

    概述 java技术体系所提倡的自动内存管理其实主要包括 ①:给对象分配内存 ②:回收给对象分配的内存对象的内存分配...

  • 4.引用

    变量:对象的引用 变量存储对象的内存地址 对象:堆内存 变量:栈内存 python不用声明变量类型,但对象有类型,...

  • java 内存布局

    Java 内存的布局主要是统计Java对象占用内存的大小。 Java对象的内存布局:对象头(Header)、实例数...

  • NSZombie(僵尸对象)

    1、内存泄漏:对象使用完没有释放,导致内存浪费。2、僵尸对象:过度释放的对象。对象可能在内存中,但对象的状态已为d...

  • Android性能优化

    内存优化基本可以分为以下几个方面:下面就分别介绍。 减少对象的内存占用 对内存对象进行复用 避免对象的内存泄漏 内...

网友评论

    本文标题:Runtime-OC对象的内存

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