一、引用计数机制:
通过给每个对象维护一个引用计数器,记录该对象当前被引用的次数。
当对象增加一次引用时,计数器加1;而对象失去一次引用时,计数器减1;当引用计数为0时,标志着该对象的生命周期结束,自动触发对象的回收释放。
引用计数的重要规则是每一个程序片段必须负责任地维护引用计数,在需要维持对象生存的程序段的开始和结束分别增加和减少一次引用计数.
二、结合Ref,AutoReleasPool,PoolManage看内存管理
理论:
Ref是引用计数的模型:
1、Ref抽象类(不能实例化,只能由子类实例化);
2、创建默认引用计数为1;//: _referenceCount(1)
3、调用retain引用计数加1;
4、调用release引用计数减1;
5、调用autorelease并没有使引用计数减1,而是交给自动释放池来管理。
AutoReleasPool自动释放池
1、AutoReleasPool是一个Ref的容器,用Vector<Ref>存储Ref中AutoRelease的成员;(std::vector<Ref*> _managedObjectArray;)
2、AutoReleasPool支持addObject,clear(vector中Ref执行release),contains,dump(打印当前Vector中Ref的引用计数的信息)
3、源代码AutoReleasPool使用方式:PoolManager::getInstance()->getCurrentPool()->addObject(this);
PoolManage池管理器
1、AutoreleasePool创建的时候PoolManager::getInstance()->push(this)把this存储;(std::vector<AutoreleasePool*> _releasePoolStack;)
2、PoolManager支持push,pop,isObjectInPools,getCurrentPool;
3、Dirctor->mainloop->每一帧中DrawScene之后PoolManager::getInstance()->getCurrentPool()->clear();清理当前Autorelease的Vector;(_managedObjectArray)
做一个测试来查看:_managedObjectArray,_releasePoolStack的内容信息:
1、_managedObjectArray元素的push顺序:
Ref->RenderState->StateBlock->SchedulerScriptHandlerEntry->GLView->FrameBuffer->CameraBackgroundDepthBrush->Camera->EventListener->Scene
2、_managedObjectArray的表结构体信息
3、mainloop在drawScene之后,清理_managedObjectArray,清理完毕之后,再次绘制页面的时候,会重复走之前的加载流程;
4、_releasePoolStack的结构体信息:
_releasePoolStack在执行首次AutoRelease方法的时候会push;若如果程序不自己push,_releasePoolStack会有一个AutoReleasPool;
三、mainloop中自动释放
分析一帧都做了什么事情,都涉及到什么,然后再来看自动释放。
Ref的子类有:
事件、Event, EventDispatcher, EventListener,
动画、Action, ActionManager, Animation, Animation3D, AnimationCache, AnimationCurve< componentSize >, AnimationFrame,;
物理、Physics3DConstraint, Physics3DObject, Physics3DShape, Physics3DWorld,PhysicsShape,
渲染、RenderState, RenderState::StateBlock
文件、联网等;
一帧之内所做的事情(FPS):
1、事件检查和处理:在每一帧开始,C2d检查事件,有则处理分发事件。
2、动画更新:ActionManager会对每一个元素注册的所有动画执行响应计算,并更新其对应的属性值;
3、默认处理物理模拟碰撞;
4、程序自定义更新;
5、UI树的遍历;UI树的遍历主要是给每一个元素计算坐标变换矩阵,以及根据指定的逻辑深度排序,生成正确的绘制顺序。每个节点别遍历之后,讲发送绘制命令至绘制栈;
6、渲染系统根据员孙的globalZorder进行绘制,绘制完毕,交换前后缓冲区,将当前帧的内容回到屏幕上;
7、poolManger释放当前所有的autorelease对象;所以我们只关心对象的创建和使用,不需要关心其释放;
每一个步骤都会计入Ref对象类型的Ref对象,所以销毁的内容就比较清楚了;