zoukankan      html  css  js  c++  java
  • 【OC底层】一个OC对象占用多少内存?

    查看一个NSObject对象占用多少内存

    1、引入头文件:

    #import <objc/runtime.h>

    #import <malloc/malloc.h>

     

    2、代码如下:

            NSObject* obj = [[NSObject alloc]init];
            
            // 获取实例对象至少需要分配的内存大小,实际真正占用的大小,8 字节
            size_t insSize = class_getInstanceSize([NSObject class]);
            NSLog(@"NSObject Size:%zd",insSize);
            // 同上
            insSize = class_getInstanceSize([obj class]);
            NSLog(@"NSObject Size:%zd",insSize);
            
            // 获取实际分配内存大小,最终分配的大小,16 字节
            size_t mSize = malloc_size((__bridge const void *)obj);
            NSLog(@"malloc Size:%zd",mSize);
            
            // 通过OC的源码可以看出配置对象内存至少有 16字节

      1>、通过 class_getInstanceSize 可以获取类对象实际占用的大小

      2>、通过 malloc_size 实际分配内存大小,最终分配的大小

     

    如下是OC的源码,可以看得出如果分配的内存小于16的话会直接设置为16

     

    可以通过内存查看工具来验证上面的说法:

    进入Debug模式,通过 Debug -> Debug Workfllow -> View Memory (Shift + Command + M)  可以打开内存查看工具

    1、进入调试模式,断点代码后,通过 po 对象,可以查看对象对应的地址

      

    (lldb) po obj
    <NSObject: 0x1002013d0>

    2、在下面Address输入框输入要查看的内存地址,回车就可查看

    通过上面的截图可以看到被选中的那个8个字节都是00,都是空的,说明根本就没有用到,实际只用到了前面的8字节

    为什么就可以这么肯定它占用了16个字节呢?因为可以看出00后面就是 03 00 00 00  了,系统内存分配都是连续一段的,中间是不会有间隙的,所以可以确定系统就是分配了 16个字节

    3、也可以通过 x 命令来查看,命令如下:

    (lldb) x 0x1002013d0
    
    0x1002013d0: f1 f0 68 7c ff ff 1d 00 00 00 00 00 00 00 00 00  ..h|............
    
    0x1002013e0: 03 00 00 00 00 01 00 00 00 36 80 02 01 00 00 00  .........6......

     一样可以看得出后8位都是00

     查看自定义对象的内存占用大小

    @interface XGPerson : NSObject
    
    @property (nonatomic,assign) int age;
    @property (nonatomic,assign) int height;
    @property (nonatomic,assign) int row;
    
    @end
    
    @implementation XGPerson
    
    @end

    像上面这个对象,里面有3个属性,都是int ,每个int类型是占4字节的,具体其它类型占多少可以去查官方文档

    同过如下代码进行测试:

            XGPerson* obj = [[XGPerson alloc]init];
            obj.age = 4;
            obj.height = 5;
            obj.row = 6;
            
            // 输出:24字节
            size_t insSize = class_getInstanceSize([XGPerson class]);
            NSLog(@"XGPerson Size:%zd",insSize);
            
            // 输出:32字节
            size_t mSize = malloc_size((__bridge const void *)obj);
            NSLog(@"malloc Size:%zd",mSize);

    再通过上面说的那种内存查看方法去看看内存

    (lldb) po obj
    <XGPerson: 0x100602ed0>
    
    (lldb) x 0x100602ed0
    0x100602ed0: d9 12 00 00 01 80 1d 00 04 00 00 00 05 00 00 00  ................
    0x100602ee0: 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

    通过内存打印,可以看得出3个属性分别各自占用了4个字节,总共是24个,那为什么 malloc_size 会输出32个呢?

    原因就是系统底层的内存对齐导致的 (内存对齐好像分配的16的倍数,像24不是16的倍数,所以被分配32,不知道我理解的对不对,请各位大神指点!)

    通过上面这个输出日志可以看得出,如果我们这个XGPerson只有2个属性,那它的分配大小和实际占用大小应该都是16,因为NSObject对象默认只用到了前8个字节

    所以只有当有3个属性的时候才会变成32个字节。

    -----------------------------

    本文参考借鉴MJ的教程视频,非常感谢.

  • 相关阅读:
    你不知道的JS系列上( 40 ) - 什么是类
    CF356E
    [HDU4135]CO Prime(容斥)
    [POJ 2888]Magic Bracelet[Polya Burnside 置换 矩阵]
    Polya定理与Burnside引理
    选举
    David与Vincent的博弈游戏[树型DP]
    Vincent的城堡
    三元组
    vue打包体积优化之旅
  • 原文地址:https://www.cnblogs.com/xgao/p/9707389.html
Copyright © 2011-2022 走看看