1. 空 Page 的判断
struct AutoreleasePoolPage {id *next; // 指向下一个可用位置id *begin(); // 页面起始位置bool empty() {return next == begin(); // next 指针回到起始位置表示为空}// 页面的边界id *begin() { return (id *)(this + 1); }id *end() { return (id *)((uint8_t *)this + SIZE); }
};
2. Pop 时的处理
void pop(void *token) {AutoreleasePoolPage *page = pageForPointer(token);id *stop = (id *)token;page->releaseUntil(stop);// 如果 page 变空且不是第一个 pageif (page->empty() && !page->parent) {// 将 page 销毁page->kill();}
}
3. 销毁机制
void kill() {// 确保是在正确的线程上assert(thread == pthread_self());// 解除与父页面的链接if (parent) {parent->child = nullptr;}// 解除与子页面的链接if (child) {child->parent = nullptr;}delete this;
}
4. 处理流程
1. 检查是否为空
if (page->empty()) {// 页面为空的处理if (page->child) {// 有子页面时不能删除return;}if (!page->parent) {// 是第一个页面时保留return;}// 其他情况可以安全删除page->kill();
}
2. 更新热页面
if (hotPage() == page) {// 如果当前页面是热页面,需要更新setHotPage(page->parent);
}
3. 内存回收
// 页面被销毁时
~AutoreleasePoolPage() {// 清理工作if (child) child->parent = parent;if (parent) parent->child = child;
}
这种机制确保了:
- 内存的有效使用
- 避免空页面占用资源
- 保持页面链表的完整性
- 线程安全的处理