4 OC 中的内存分配以及内存对齐

目录

一  OC  中的内存分配


一  OC  中的内存分配

 

student 结构体明明是20?为什么是24个字节,因为结构体会按照本身成员变量最大的内存进行对齐,最大成员变量是8个字节,因此就是8的倍数,24个字节。

class_getInstanceSize 返回的是该类内存对齐之后的成员变量的内存空间,你需要多少,计算多少。

malloc_size  是实际系统分配的内存空间

 

 

#import <Foundation/Foundation.h>

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


// 模拟 NSObject 的实现
struct NSObject_IMPL
{
	Class isa;
};


// 模拟Student 的实现
struct Student_IMPL
{
	struct NSObject_IMPL IVARS;// 8
	int _no;// 4
	int _age;// 4
	int _height;// 4
}; // 以上实际是20个字节,由于必须是8的倍数,所以是24个字节



@interface Student:NSObject
{

	@public
	int _no;
	int _age;
	int _height;
}


@end


@implementation Student


@end

int main(int argc, const char * argv[]) {
	@autoreleasepool {
	    // insert code here...
	    Student *stu1 = [[Student alloc]init];
		// 24
		NSLog(@"%zd",sizeof(struct Student_IMPL)); 
		// 24 - 32
		NSLog(@"%zd -- %zd",class_getInstanceSize([Student class]),malloc_size((__bridge const void *)(stu1)));
		
		
	}
	return 0;
}

虽然结构体只需要24个字节,可以看出来student 实例对象占用的字节是32个字节

 

前面也有讲到  allozWithZone 方法调用中

    inline size_t instanceSize(size_t extraBytes) const {
        if (fastpath(cache.hasFastInstanceSize(extraBytes))) {
            return cache.fastInstanceSize(extraBytes);
        }
    
        // extraBytes 一般是传递的是0
        size_t size = alignedInstanceSize() + extraBytes;
        // CF requires all objects be at least 16 bytes.
        if (size < 16) size = 16;
        return size;
    }



id 
_class_createInstanceFromZone(Class cls, size_t extraBytes, void *zone)
{
    void *bytes;
    size_t size;

    // Can't create something for nothing
    if (!cls) return nil;

    // Allocate and initialize
    size = cls->alignedInstanceSize() + extraBytes;

    // CF requires all objects be at least 16 bytes.
    if (size < 16) size = 16;

    if (zone) {
        bytes = malloc_zone_calloc((malloc_zone_t *)zone, 1, size);
    } else {

    // 这个位置传递的就是24,但是实际分配的内存确实32,所以还是要看calloc 底层的实现
        bytes = calloc(1, size);
    }

    return objc_constructInstance(cls, bytes);
}

calloc 的源码实现,去苹果源码开源下载 找到malloc 的源码包文件

https://opensource.apple.com/tarballs/libmalloc/

在 malloc.c 文件中找到的calloc 函数的实现

 

 

void *
calloc(size_t num_items, size_t size)
{
	void *retval;
	retval = malloc_zone_calloc(default_zone, num_items, size);
	if (retval == NULL) {
		errno = ENOMEM;
	}
	return retval;
}


void *
malloc_zone_calloc(malloc_zone_t *zone, size_t num_items, size_t size)
{
	void *ptr;
	size_t alloc_size;
	if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) {
		internal_check();
	}
	if (os_mul_overflow(num_items, size, &alloc_size) || alloc_size > MALLOC_ABSOLUTE_MAX_SIZE){
		errno = ENOMEM;
		return NULL;
	}

	ptr = zone->calloc(zone, num_items, size);
	
	if (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);
	}
	return ptr;
}

以上说了那么多,这这个源码中有一个 NANO_MAX_SIZE 这个宏定义,堆上分配内存的时候,系统把一块块内存都划分好的

即使你不够16个字节,也给你分配16个字节,这里都是16的倍数。

#define NANO_MAX_SIZE            256 /* Buckets sized {16, 32, 48, 64, 80, 96, 112, ...} */

 

所以以上结构体只需要24个字节,但是系统就是分配给你32个字节的内存

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值