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的教程视频,非常感谢.

  • 相关阅读:
    DNNClassifier 深度神经网络 分类器
    浏览器对MP4视频 帧宽度 高度的兼容性
    UnicodeEncodeError:'latin-1' codec can't encode character
    文件夹下 文件计数
    the largest value you actually can transmit between the client and server is determined by the amount of available memory and the size of the communications buffers.
    the “identity” of an object
    广告特征 用户特征
    如果一个维度全覆盖,则有效维度应该对该维度全覆盖
    a high-level neural networks AP
    使用 LDA 挖掘的用户喜好主题
  • 原文地址:https://www.cnblogs.com/xgao/p/9707389.html
Copyright © 2011-2022 走看看