对cocos2d-x的内存管理机制的理解,一直是有疑问的,但由于其安全的机制,让我没有花心思去考虑。但最终也要面对。内存管理的基本概念,引用计数和自动管理池,暂且不提。且就一点疑问进行分析和总结。
这一点疑问是:
在每个帧循环结束后,每个对象都会release一遍,那么几遍后不就清除了?
解决的关键是没能正确理解自动管理池的机制。我能力尚浅,看不懂源代码,在网上也没找到能够理解的解释。不过还好AutoreleasePool的源代码注释帮到了我:
/** * Clear the autorelease pool. * * It will invoke each element's `release()` function. * * @js NA * @lua NA */ void clear();
第一行,Clear the autorelease pool,这说明在一次帧循环结束前,除了调用每一个内存池中对象的release函数,该内存池也将清空一遍,也就是说,一个帧循环下来,这个内存池将空空如也。所以以上疑问就解决了,内存管理中的对象,至多只会被release一次而已。
那么,一个帧循环下来,那些引用计数大于等于1,也就是没有自动清除的对象怎么办呢?它们将不再被AutoreleasePool管理。那么被谁管理呢?
1.渲染树根节点,也就是scene
2.程序员自己
自己管理,也就是手动对对象使用retain和release,我觉得这很不安全,如果忘记了就惨了。
现在的问题就是,谁来管理渲染树根节点?
其实答案很简单,不过我现在才意识到这一点的重要性。正是由于Director中有一个 Vector<Scene*> _scenesStack ,它管理着游戏的场景对象,也就是管理着渲染树。那么,最终的资源管理的大门,确实是由Director把守着。在切换场景的时候,当前游戏场景也会被清除,那么最终自动管理的资源也将被清除。还是看注释简单:
/** Ends the execution, releases the running scene. * @lua endToLua */ void end();
因此,Director对场景的管理,不仅仅是切换,更重要的是管理了场景中渲染树的释放。