Cocos2dx memory management mechanism (2)

Source: Internet
Author: User

Next, we will continue the analysis in the previous article. We know that an automatically managed object will be put into the autoreleasepool after it comes out of the new one. How will the object be deleted next?


First of all, we need to know that the cocos2d-x engine thread is a single thread, it does not stop calling a main loop to draw the current Scene, while some automatically released objects are managed.


1. Start positioning now. We know the cocos2dx program entry under win32.

CCApplication::sharedApplication()->run();

There is such a sentence in the run method.

CCDirector::sharedDirector()->mainLoop();

View the mainLoop method.

void CCDisplayLinkDirector::mainLoop(void){    if (m_bPurgeDirecotorInNextLoop)    {        m_bPurgeDirecotorInNextLoop = false;        purgeDirector();    }    else if (! m_bInvalid)     {         drawScene();              // release the objects         CCPoolManager::sharedPoolManager()->pop();             }}

In this main loop, drawScene () is used to render the scene, and CCPoolManager: sharedPoolManager ()-> pop () is used to release the objects in the pool automatically.


2. Before analyzing the pop release object, it is necessary to understand why the pool needs to be released automatically.


The following explanation is excerpted from: http://blog.leafsoar.com/archives/2013/06-04.html


We know that the cocos2d-x uses an automatic release pool, Automatic Object Management, and that's all! Why? Why does the pool need to be automatically released? What role does it play in the entire framework! Before learning about this, we need to know the process that CCObject has taken from its initial creation to its final destruction. Here, one leaf summarizes the following points (Key Points):

  • The newly created object, and in order to ensure that it will not be released before use (at least let it survive one frame), Self-reference (that is, initially 1)
  • To determine whether it is actually used, you need to release your reference at an appropriate time.
  • The timing is exactly when the frame is too large.
  • The object after the frame is too large. If it is used, it will be used. If it is not used, it will be discarded!
  • Since its own reference has been removed, its reference is managed by the user (in general, the chain reaction that forms a tree structure internally, such as CCNode ).
  • A chain reaction, that is, if an object is released, it will also release the object it references.

    The above is a general process of an object. We divide the object into two periods. One is the initial period and the Self-reference is 1. (if it is 0, the object will be released. This is the basic principle, so it must be greater than 0), and the other is the use period. As mentioned above, in order to ensure that objects in the creation period are not destroyed, self-reference (not actually used) is initialized to 1, which means we need a proper time,.

    When? When the frame is too large! (This ensures that the current frame can correctly use the object without being destroyed .) How to release? Because it is a self-reference, we cannot access it in other ways, so we have an automatic release pool, And we convert "self-reference" to "Auto Release pool reference" in disguise ", to mark an object in the creation period ".

    ThenWhen the frame is too large, the "Release pool reference" is released by automatically releasing the pool management, which means that the "own reference" is removed ". Objects after excessive frames are managed by users.


    Conclusion: by understanding the above paragraph, we can understand:

      When an object is just created (create, new + autorelease), the pool is automatically released to retain reference to the object ("reference itself"), so that the reference count is 1.
        During Frame Transition, the CCPoolManager: sharedPoolManager ()-> pop () in the main loop of the game. If a method is called once, the "self-reference" is automatically removed ", in fact, all objects in the automatically released pool are release once. Therefore, the object can have at least one frame. (Of course, if the reference count of an object is 0, the object will be released .)
          Of course, to keep the object from being released, you must have a management object (which is actually an object) to "use" the object, that is, the management object must be referenced to the object, in this way, the object will be managed to retain the object, so that its reference count will not be 0.
            Therefore, the purpose of removing the Auto Release pool's own reference (pop) to the object is to grant the reference right to the management object that actually uses the object. ( Here we can also explain a problem we may encounter during programming: after creating a variable, we suddenly encounter a memory error when using it, obviously, there is a lack of reference to the management object, and the solution is also very simple. To use the management object of this object, retain it.) 3. automatically release the pool to release the reference process (pop)

            First, we enter the pop () method:

            void CCPoolManager::pop(){    if (! m_pCurReleasePool)    {        return;    }     int nCount = m_pReleasePoolStack->count();    m_pCurReleasePool->clear();       if(nCount > 1)      {        m_pReleasePoolStack->removeObjectAtIndex(nCount-1);//         if(nCount > 1)//         {//             m_pCurReleasePool = m_pReleasePoolStack->objectAtIndex(nCount - 2);//             return;//         }        m_pCurReleasePool = (CCAutoreleasePool*)m_pReleasePoolStack->objectAtIndex(nCount - 2);    }    /*m_pCurReleasePool = NULL;*/}

            In this method, we can know that the release process is as follows:

            In the previous article Cocos2d-x Memory Management Mechanism (1) we already know that the CCPoolManager object automatic release management class stores a current object automatic release pool and an object release pool array.


            In the pop method, the clear operation is performed on the automatic release pool of the current object, which is obviously to unreference all objects in the current release pool. Enter the clear method as follows:

            void CCAutoreleasePool::clear(){    if(m_pManagedObjectArray->count() > 0)    {        //CCAutoreleasePool* pReleasePool;#ifdef _DEBUG        int nIndex = m_pManagedObjectArray->count() - 1;#endif        CCObject* pObj = NULL;        CCARRAY_FOREACH_REVERSE(m_pManagedObjectArray, pObj)        {            if(!pObj)                break;            --(pObj->m_uAutoReleaseCount);            //(*it)->release();            //delete (*it);#ifdef _DEBUG            nIndex--;#endif        }        m_pManagedObjectArray->removeAllObjects();    }}


            We can see in the for loop -- (pObj-> m_uAutoReleaseCount); this is to remove the Automatic Object Management for the referenced object, and the automatic management value is reduced by one.


            When an object is added to the Auto Release pool, m_uAutoReleaseCount = 1 indicates automatic management for the Auto Release pool. Then, after 1 is subtracted, m_uAutoReleaseCount = 0 indicates that the auto release pool is not managed.


            We can also note that CCARRAY_FOREACH_REVERSE uses reverse order to release the reference. We can also guess that the automatic release pool uses a stack structure (FILO ).


            -- M_uAutoReleaseCount. That is, m_pManagedObjectArray-> removeAllObjects (); all objects in the pool will be automatically released for removal, so we will find that the removal process is actually a release operation on the object, because the m_uReference value after the object autorelease is 1, the release becomes 0, and the object is automatically released.


            So after this clear, all objects in the object pool in the current automatic management are removed from the reference.


            Then let's go back to the pop method,

            if(nCount > 1)      {        m_pReleasePoolStack->removeObjectAtIndex(nCount-1);//         if(nCount > 1)//         {//             m_pCurReleasePool = m_pReleasePoolStack->objectAtIndex(nCount - 2);//             return;//         }        m_pCurReleasePool = (CCAutoreleasePool*)m_pReleasePoolStack->objectAtIndex(nCount - 2);    }

            After the current object is automatically released to the clear pool, you need to delete the object from the automatically released pool array; then, use the second Auto Release pool in the array as the current Auto Release pool.

            From here, we can also roughly understand that the automatic release of the pool array is essentially a stack structure, but it is implemented through arrays.

            The process of automatically releasing the pool to unreference is roughly like this!


            Iv. Summary

            These two articles roughly describe the memory management in cocos2dx. In fact, there are two aspects in summary:

            ① Add objects to the Auto Release pool for Automatic Management (creation period );

            ② The automatic release pool removes the automatic management of objects and is handed over to the objects using this object for Management (use period ).

            There should be no problems in understanding the process!









Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.