首页 > 技术文章 > Director是内存管理的最后一道门

demon90s 原文

  对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对场景的管理,不仅仅是切换,更重要的是管理了场景中渲染树的释放。

推荐阅读