一個(gè) NSOject 對(duì)象所占內(nèi)存大小 ? (64bits)

  1. 系統(tǒng)實(shí)際分配了 16 字節(jié)給 NSOject對(duì)象, 通過(guò) malloc_size 函數(shù)獲得, 查看源碼
    )可以知道平臺(tái)底層對(duì)分配內(nèi)存空間做了對(duì)齊操作, 在 libmalloc 中的宏定義 NANO_MAX_SIZE = 256 是說(shuō) nano 這種分配空間方式里面最大分配 256 個(gè)字節(jié), 備注里面有說(shuō)是 16 的倍數(shù)
  2. NSOject 對(duì)象內(nèi)部使用了 8 個(gè)字節(jié), 通過(guò) class_getInstanceSize 函數(shù)獲得, 也就是說(shuō)該函數(shù)獲取的是最少需要的字節(jié)數(shù), 是結(jié)構(gòu)體對(duì)齊后的字節(jié)數(shù), 與 sizeof 計(jì)算出來(lái)的數(shù)值一樣
  • iOS 源碼地址
https://opensource.apple.com/tarballs
  • 轉(zhuǎn) iOS --> 64bits (arm64), 可以查看翻譯成 C 的代碼 中類(lèi)的結(jié)構(gòu)體
$ xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main-arm64.cpp
# 轉(zhuǎn)換 LLVM 命令
$ clang -emit-llvm -S main.m 
  • 記得引入以下頭文件
#import <objc/runtime.h>
#import <malloc/malloc.h>
  • 下面是我的測(cè)試代碼, 放入 main.m 就可以

#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <malloc/malloc.h>

@interface Student : NSObject
{
    @public
    int _no;
    int _age;
}
@end
@implementation Student
@end

/**
 * 一個(gè) NSOject 對(duì)象所占內(nèi)存大小 ? (64bits)
 * 系統(tǒng)分配了 16 字節(jié)給 NSOject 對(duì)象, 通過(guò) malloc_size 函數(shù)獲得
 * 但 NSOject 對(duì)象內(nèi)部使用了 8 個(gè)字節(jié), 通過(guò) class_getInstanceSize 函數(shù)獲得
 */
void objc_instance_size (void);
void student_instance_size (void);
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        objc_instance_size();
        student_instance_size();
    }
    return 0;
}

/**
 * NSOject_Implementation
 * clang 編譯后的 NSObject 實(shí)質(zhì)為一個(gè) C 的結(jié)構(gòu)體如下
 * 數(shù)據(jù)結(jié)構(gòu)
 */
struct NSObject_IMPL {
    Class isa;
    //    typedef struct objc_class *Class;
    //    Class 指向結(jié)構(gòu)體的指針
    //    指針在 64bits 上是 8 個(gè)字節(jié)
};
// NSObject.h
//@interface NSObject <NSObject> {
//    Class isa  OBJC_ISA_AVAILABILITY;
//}
void objc_instance_size () {
    
    NSObject *objc = NSObject.alloc.init;
    
    size_t objc_sizes = class_getInstanceSize(objc.class);
    // 獲取 NSOject 類(lèi)的實(shí)例對(duì)象中成員變量?jī)?nèi)存對(duì)齊后所占內(nèi)存的大小(最少需要的空間, 值和 sizeof 計(jì)算的一樣)
    NSLog(@"objc_sizes  => %zd", objc_sizes);
    /* class_getInstanceSize 源碼中調(diào)用了下面的函數(shù), 所以是對(duì)齊過(guò)的 ivar size
     // Class's ivar size rounded up to a pointer-size boundary.
     uint32_t alignedInstanceSize() {
         return word_align(unalignedInstanceSize());
     }
     */
    
    size_t malloc_sizes = malloc_size((__bridge const void *)(objc));
    // 獲取 objc 指針指向所占內(nèi)存的大小(實(shí)際開(kāi)辟的, 通過(guò)源碼可以看到 iOS 是 16 的倍數(shù)對(duì)齊 libmalloc 中的宏定義 NANO_MAX_SIZE)
    NSLog(@"malloc_sizes => %zd", malloc_sizes);
    /* 在 _class_createInstanceFromZone 也就是 allocWithZone 的底層實(shí)現(xiàn)中調(diào)用了以下函數(shù)來(lái)計(jì)算實(shí)例大小
     
     size_t instanceSize(size_t extraBytes) {
         size_t size = alignedInstanceSize() + extraBytes;
         // CF requires all objects be at least 16 bytes.
         if (size < 16) size = 16;
         return size;
     }
     */
        
    
    // OC 轉(zhuǎn)成 CPP, 不同的平臺(tái)轉(zhuǎn)換出來(lái)的代碼是不一樣的
    // 轉(zhuǎn) iOS  -> 64bits (arm64)
    // xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main-arm64.cpp
    // 源碼: https://opensource.apple.com/tarballs

}


void student_instance_size () {
    /* clang 編譯后的 Student 實(shí)質(zhì)為一個(gè) C 的結(jié)構(gòu)體如下 */
    struct Student_IMPL {
        struct NSObject_IMPL NSObject_IVARS;
        int _no;
        int _age;
    };
        
    Student *std = Student.alloc.init;
    std->_no = 2;
    std->_age = 10;
    
    size_t malloc_sizes = malloc_size((__bridge const void *)(std));
    // 獲取 std 指針指向所占內(nèi)存的大小
    NSLog(@"std_malloc_sizes => %zd", malloc_sizes);
    
    struct Student_IMPL *std_imp = (__bridge struct Student_IMPL *)(std);
    NSLog(@"std_imp->_no: %d \t std_imp->_age: %d", std_imp->_no, std_imp->_age);
}


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容