Principle of cocos2d-x recovery pool, cocos2d-x recovery

Source: Internet
Author: User

Principle of cocos2d-x recovery pool, cocos2d-x recovery

 

Cocos2d-x comes from the cocos2d-iphone, and in order to be consistent with Objective-c, the cocos2d-x also uses the reference counting and automatic recovery memory management mechanism.

To realize automatic memory reclaim, You need to inherit from the cocos2d-x's root class CCObject. Of course, automatic release will affect the performance.

 

There are many static workshop methods in the cocos2d-x, such as those starting with create, these static workshop method to create objects are using autorelease, imagine if you do not need autorelease,

CCObject * create () {CCObject * ret = new CCObject (); return ret ;}

The reference in the function ends at the end of the function, but the other party is not released. If the returned ret is not referenced or released by the user, memory leakage occurs. Therefore, joining autorelease is a good solution.

 

Take a look at the two fields and methods of CCObject:

Protected: // reference count unsigned int m_uReference; // The number of automatic releases is previously bool m_bManaged; whether to use automatic release of unsigned int m_uAutoReleaseCount; public: void release (void ); void retain (void); CCObject * autorelease (void); unsigned int retainCount (void );

There is such a principle: Who references retain and release, and then retain and release when the object is passed to the value (to avoid the possibility that release will release the object first when passing the value to itself), call the release method, when the reference count is 0, the object is deleted.

How is the memory management autorelease implemented? Go to autorelease and see that the following function is called:

CCPoolManager: sharedPoolManager ()-> addObject (this); Add the object to the recycle pool

void CCAutoreleasePool::addObject(CCObject* pObject){    m_pManagedObjectArray->addObject(pObject);    CCAssert(pObject->m_uReference > 1, "reference count should be greater than 1");    ++(pObject->m_uAutoReleaseCount);    pObject->release(); // no ref count, in this case autorelease pool added.}

The function adds the object to the management array, then automatically releases the Count + 1, and then releases the reference count-1.

When you create an object, new sets the reference count to 1. After autorelease is called, add it to the recycle pool, and then release reference count to 1. Is the reference count 0 at this time?

The answer is definitely not. If it is 0, the object will be deleted. The data structure in the cocos2d-x is converted to this memory management setting, such as CCArray. When addObject is called for array, retain is called to add 1 to the reference count, and release is called when array calls removeObject. After a collection pool is added, the reference belongs to the collection pool. When a frame ends and the collection pool is released, all objects in the collection pool call release. If no other object references this object at this time, the object will be deleted.

 

Let's take a look at the calls in the mainLoop of the Main Loop:

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

When sharedPoolManager ()-> pop () is called at the end of each frame, the recycle pool at the top of the stack is released,

Void CCPoolManager: pop () {if (! M_pCurReleasePool) {return;} int nCount = m_pReleasePoolStack-> count (); m_pCurReleasePool-> clear (); if (nCount> 1) {// release the recycle pool m_pReleasePoolStack-> removeObjectAtIndex (nCount-1); m_pCurReleasePool = (CCAutoreleasePool *) m_pReleasePoolStack-> objectAtIndex (nCount-2 );}}

In this case, all objects in the pool will be release. If no other objects (scenarios, layers, arrays, etc.) are referenced by them, these objects will be deleted.

After a new frame starts, when the first object calling autorelease internally calls getCurReleasePool (), if there is no recycle pool in the stack, a recycle pool will be pushed, sharedPoolManager () -> push ().

CCAutoreleasePool* CCPoolManager::getCurReleasePool(){    if(!m_pCurReleasePool)    {        push();    }    CCAssert(m_pCurReleasePool, "current auto release pool should not be null");    return m_pCurReleasePool;}

 

 

 

It can be seen that every frame of the recycle pool needs to be created and deleted, and the added object enters the recycle pool, so the performance will of course be affected. When there are many objects in the recycle pool, the performance will be obvious.

Solution 1: Do not use the automatic recycle pool if the performance requirement is high.

 

Method 2: manually release and create a recycle pool

CCPoolManager::shardPoolManager()->push();for(int i=0; i!=n; ++i){     objArray[i]->autorelease();}CCPoolManager::shardPoolManager()->pop();

In this way, the automatically released objects will not be concentrated at the end of a frame.

 

 

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.