前言:在上一篇文章中,我们了解到,OC 底层的alloc 到底做了哪些事情。总结起来就是:
1、计算内存大小
2、开辟内存空间
3、对象关联类
先研究一下 内存大小的问题吧
1、
_class_createInstanceFromZone(Class cls, size_t extraBytes, void *zone,
intconstruct_flags =OBJECT_CONSTRUCT_NONE,
boolcxxConstruct =true,
size_t*outAllocatedSize =nil)
{
ASSERT(cls->isRealized());
// Read class's info bits all at once for performance
boolhasCxxCtor = cxxConstruct && cls->hasCxxCtor();
boolhasCxxDtor = cls->hasCxxDtor();
boolfast = cls->canAllocNonpointer();
size_tsize;
size = cls->instanceSize(extraBytes);
if(outAllocatedSize) *outAllocatedSize = size;
通过这段代码可以看到 计算字节大小的主要是以下这一段代码
size = cls->instanceSize(extraBytes);
那我们 去探究一下它究竟做了什么
inline size_t instanceSize(size_t extraBytes) const {
if (fastpath(cache.hasFastInstanceSize(extraBytes))) {
return cache.fastInstanceSize(extraBytes);
}
size_t size = alignedInstanceSize() + extraBytes;
// CF requires all objects be at least 16 bytes.
if (size < 16) size = 16;
return size;
}
注: slowpath与fastpath与编译器的优化相关,其可以提高编译器的工作效率,后面再做详细阐述,目前不考虑编译器优化 那么就会走到 关键代码
size_t size = alignedInstanceSize() + extraBytes;
size 即为 对齐以后的内存大小 ,其中extraBytes为 函数透传过来的 参数为0
所以主要分析一下 alignedInstanceSize() ;
// Class's ivar size rounded up to a pointer-size boundary.
uint32_t alignedInstanceSize() const {
return word_align(unalignedInstanceSize());
}
static inline uint32_t word_align(uint32_t x) {
return (x + WORD_MASK) & ~WORD_MASK;
}
逐渐水落石出,发现其实 内存对其的核心代码 在这里
(x + WORD_MASK) & ~WORD_MASK
// 其中
define WORD_MASK 7UL
其中x 表示的是 该对象 对齐之前 实际分配的内存空间大小
这里 带入一下,假设 它是6 然后 6+7 = 13 用2进制表示为
0000 1101
7用二进制表示为 0000 0111
那么~7 的二进制表示为 1111 1000
那么 13&7 的结果为
0000 1101 & 1111 1000
0000 1000 转换为10进制为8
从这里可以看出 这里面是将 未对齐的空间做一个 关于8 的对齐,即将空间分配为8的倍数。
然后我们继续往下看代码 if (size < 16) size = 16;
看到这里发现,苹果又对 分配的空间进一步优化 如果此次分配的空间小于16那么就给到它16
总结
这里我们探索到了字节对齐的机制,苹果会对未对齐的空间进行扩大,扩大到8的倍数,如果不足16并给它分配16个字节 。
网友评论