内存管理的两种实现

内存管理的两种实现

通过内存块头部管理引用计数

将引用计数保存在对象占用的块头部变量中。
即实现一个结构体

1
2
3
4
5
struct obj_layout {
char padding[__BIGGEST_ALIGNMENT__ - ((UNP % __BIGGEST_ALIGNMENT__)
? (UNP % __BIGGEST_ALIGNMENT__) : __BIGGEST_ALIGNMENT__)];
NSUInteger retained;
};

在结构体中保存当前这个变量的引用计数。

通过计数引用表来实现计数管理

而通过对Foundation框架的逆向,可以发现苹果的实现是通过计数表来保存每个实例变量的引用计数。

在计数表中,每个内存对象地址为键值,指向一个计数值。

两种计数方式的对比:

1,通过内存块头部管理引用计数,
代码简单,不用维护一个计数表。
可以统一管理引用技术的内存与对象的内存块。负责计数的内存块与对象本身的内存块是在一起的。

2,通过哈希表实现引用计数,
在创建分配内存块的时候不需要考虑内存块头部的分配
哈希表中有记录各个内存块的地址,可以通过这个追溯到各个具体的实例变量。

在实际调试的过程中,只要计数表没有被破坏,可以很方便的通过引用计数表来追踪各个对象的计数。
同时,统一管理计数的时候,不需要考虑由于单个内存块出现故障,导致该内存对象的计数值丢失的问题。