We continue with memory analysis in step 3 of the previous article

Alloc object source code analysis – part 1

The last chapter studied the size occupied by different types in the content. So let’s move on to step three and we’ll start with two structs

struct LGStruct1 { double a; // 8 [0 7] char b; // 1 [8] int c; // 4 (9 10 11 [12 13 14 15] short d; // 2 [16 17] 24 }struct1; struct LGStruct2 { double a; // 8 [0 7] int b; // 4 [8 9 10 11] char c; // 1 [12] short d; // 2 (13 [14 15] 16 }struct2; struct LGStruct3 { double a; // 8 [0 7] int b; // 4 [8 9 10 11] char c; // 1 [12] short d; // 2 (13 [14 15] int e; // 4 [16 17 18 19] struct LGStruct1 str; //24 (20 21 22 23 [24...46] 48 }struct3; NSLog(@"%lu-%lu-%lu",sizeof(struct1),sizeof(struct2),sizeof(struct3)); **2021-09-02 09:13:47.620830+0800 001- Memory alignment rule [20249:1936263] 24-16-48**Copy the code

The printed result shows that the number and type of attributes in the structure are the same, but the size of the structure is different.

Conclusion:
  1. Properties are stored in multiples of size, CPU reads in integer multiples, space to time, faster
  2. Object structs are aligned to 16 bytes

Let’s go back to our object and add a few properties to person

LGPerson *person = [LGPerson alloc]; person.name = @"stone"; person.nickName = @"ios"; person.age = 18; Person. Height = 190.5; person.c1 = 'a'; person.c2 = 'b'; NSLog(@" memory sizeof object type --%lu",sizeof(person)); NSLog(@" actual memory size of object --%lu",class_getInstanceSize([person class])); NSLog(@" system allocated memory size --%lu",malloc_size((__bridge const void *)(person))); 2021-09-02 09:43:11.015921+0800 001- Memory Alignment rule [20462:1970436] Object type Memory size --8 2021-09-02 09:43:11.016650+0800 001- Memory Alignment Rule [20462:1970436] Actual memory size of the object --40 2021-09-02 09:43:11.016747+0800 001- Memory alignment Rule [20462:1970436] Allocated memory size --48Copy the code

As you can see, Apple has made some optimizations to store attributes so that int char uses 8 bytes of memory.

Look again at how the class_getInstanceSize function calculates the size of an object. Objc4-818.2 objC4-818.2 objC4-818.2

 uint32_t alignedInstanceSize() const {
    return word_align(unalignedInstanceSize());
    }
 static inline size_t word_align(size_t x) {
    return (x + WORD_MASK) & ~WORD_MASK;
    }  
Copy the code

Class_getInstanceSize performs an 8-byte alignment of (x + WORD_MASK) & ~WORD_MASK after calculating the object’s space, the same 16-byte alignment as when the object was alloc

Malloc_size returns the memory allocated by the system to the object, starting with the alloc method and using calloc

calloc(size_t num_items, size_t size) { return _malloc_zone_calloc(default_zone, num_items, size, MZ_POSIX); } _malloc_zone_calloc(malloc_zone_t *zone, size_t num_items, size_t size, malloc_zone_options_t mzo) { MALLOC_TRACE(TRACE_calloc | DBG_FUNC_START, (uintptr_t)zone, num_items, size, 0); void *ptr; if (malloc_check_start) { internal_check(); } PTR = zone->calloc(zone, num_items, size); if (os_unlikely(malloc_logger)) { malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE | MALLOC_LOG_TYPE_CLEARED, (uintptr_t)zone, (uintptr_t)(num_items * size), 0, (uintptr_t)ptr, 0); } MALLOC_TRACE(TRACE_calloc | DBG_FUNC_END, (uintptr_t)zone, num_items, size, (uintptr_t)ptr); if (os_unlikely(ptr == NULL)) { malloc_set_errno_fast(mzo, ENOMEM); } return ptr; }Copy the code

Find one->calloc(zone, num_items, size); But can not click in, continue to go down through the way of assembly.

I found the key function

#define SHIFT_NANO_QUANTUM 4 #define NANO_REGIME_QUANTA_SIZE (1 << SHIFT_NANO_QUANTUM) // 16 static MALLOC_INLINE size_t  segregated_size_to_fit(nanozone_t *nanozone, size_t size, size_t *pKey) { size_t k, slot_bytes; if (0 == size) { size = NANO_REGIME_QUANTA_SIZE; // Historical behavior} //k = (size + 16-1) >> SHIFT_NANO_QUANTUM;  // round up and shift for number of quanta // slot_bytes = k << 4 slot_bytes = k << SHIFT_NANO_QUANTUM; // multiply by power of two quanta size *pKey = k - 1; // Zero-based! return slot_bytes; }Copy the code

Conclusion: When the object is finally created, the apple is aligned to 16 bytes.

Step 4 The nature of the object

Using the clang compiler, turn the oc into a c++ file and see what happens

Clang-rewrite-objc main.m -o main.cpp //UIKit error clang-x objective-c-rewrite-objc-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk main.m // xcrun-sdk iphonesimulator clang-arch arm64-rewrite-objc main.m -o Iphoneos clang-arch arm64-rewrite-objc main.m -o main-arm64.cpp //4, compile xcrun-sdk iphoneos clang-arch arm64-rewrite-objc main.m -o main-arm64.cppCopy the code

After Clang is compiled, we see that objects are structures

#ifndef _REWRITER_typedef_NSObject
#define _REWRITER_typedef_NSObject
typedef struct objc_object NSObject;
typedef struct {} _objc_exc_NSObject;
#endif

struct NSObject_IMPL {
	Class isa;
};

extern "C" unsigned long OBJC_IVAR_$_LWPerson$_LWname;
extern "C" unsigned long OBJC_IVAR_$_LWPerson$_age;
struct LWPerson_IMPL {
	struct NSObject_IMPL NSObject_IVARS;
	double  height;
	NSString *_LWname;
	NSInteger _age;
};

// @property(nonatomic, copy)NSString *LWname;
// @property(nonatomic,assign)NSInteger age;
/* @end */

// @implementation LWPerson

struct NSObject_IMPL {
    Class isa;
};
Copy the code
  • The Class type is actually a pointer to a structure of type objC_class, the underlying implementation of all classes. Therefore, we speculate that ISA may have an important relationship with class information, and the specific relationship will be explored below.

  • What’s the difference between the underlying implementation of NSObject and the underlying implementation of objects? The structure of both member variables is Class ISA, so there must be an inheritance relationship. The bottom layer of all objects is derived from ObjC_Object, and basically all objects in OC are derived from NSObject, but the real bottom implementation is the struct type of objC_Object.

The essence of an object isa structure. The isa in an object refers to the isa of object

Finally, two flow charts are attached for further study