当前位置:网站首页>201215-03-19 - cocos2dx memory management - specific explanation "recommended collection"
201215-03-19 - cocos2dx memory management - specific explanation "recommended collection"
2022-07-07 21:05:00 【Full stack programmer webmaster】
Hello everyone , I meet you again , I'm the king of the whole stack .
because cocos2dx Our use c++ Written , So memory management is just a trap , If you don't understand memory but business logic , What else are you playing c++, I watched this thing for a long time today , In fact, it is understood in essence , But there is a barrier that cannot be crossed , Finally, it was done tonight , So I want to share with you . Strive for me to put the high-quality essence of the Internet through my own understanding . Share it with you .
There are generally two ways to manage memory , Reference counting and garbage collection .
We cocos2dx Reference counting is used , And very hot java It's garbage collection . Reference count , Specific explanation of garbage collection :
Reference count : By maintaining a reference counter for each object , Record the number of times the object is currently referenced .
When an object adds a reference , Add one counter : And lose a quote , Counter minus one ; When count is 0 when . Marks the end of the life cycle of the object . Actively trigger the recycling and release of objects .
Reference counting solves the problem of object lifecycle management , But the problems of heap fragmentation and cumbersome management still exist . Garbage collection : He introduced his own active memory payback period , Try to completely liberate the program ape from the complex memory management task . He will actively track all references of each object , In order to find the object in use , Then there are real estate enterprises and objects that are no longer needed . Garbage collection period is usually executed as a separate low-level thread , Clear and recycle objects that have died or have not been used for a long time in the memory heap under unpredictable circumstances .
Let's focus on reference counting , Its principle is that we reference an object , Just add one to the reference count of the object , If you lose a reference and an object, reduce the reference count by one . stay cocos2dx The way is retain and release, Let's see CCObject. stay CCObject There's a property in it m_uReference Is the reference count .
CCObject::CCObject(void)<span style="white-space:pre"> </span>
: m_nLuaID(0)
, m_uReference(1) // when the object is created, the reference count of it is 1 Note that there , Default this m_uReference yes 1 Of
, m_uAutoReleaseCount(0)
{
static unsigned int uObjectCount = 0;
m_uID = ++uObjectCount;
}void CCObject::retain(void)
{
CCAssert(m_uReference > 0, "reference count should greater than 0");
++m_uReference;
}retain Method , Each time will be m_uReference Add one
void CCObject::release(void)
{
CCAssert(m_uReference > 0, "reference count should greater than 0");
--m_uReference;
if (m_uReference == 0)
{
delete this;
}
}release Each time will be m_uReference Minus one , And assume 0 Then delete fall .
Suppose we manage manually , Just use the above method .
But we mainly say that we actively manage , Taking the initiative to manage yourself is actually that you just work . We will hand over the issue of release to Cocos2dx Engine to release , There is no need for us to manually call release
Generally, there will be one in our class create Method . This method is probably like this
MyScene * MyScene::create()
{
MyScene *pRet = new MyScene;
if (pRet && pRet->init())
{
pRet->autorelease();<span style="white-space:pre"> </span>// Note that there , At this time, we give this object to the engine , We don't need to release manually again , Just wait for the engine to release itself
return pRet;
}
else
{
CC_SAFE_DELETE(pRet);
}
return NULL;
}Some people will ask . You simply don't release because of such a sentence , It's up to the engine , How did you achieve . Is this thing reliable , Don't panic , Let's enter the method to see
CCObject* CCObject::autorelease(void)
{
CCPoolManager::sharedPoolManager()->addObject(this); // Let's go in again , See the following method
return this;
}
void CCPoolManager::addObject(CCObject* pObject)
{
getCurReleasePool()->addObject(pObject); // Let's go in again . See the following method
}
void CCAutoreleasePool::addObject(CCObject* pObject)
{
m_pManagedObjectArray->addObject(pObject); // Here suppose we continue to go down , Then we will eventually find one pObject.retain The method of ,
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.
}First of all, we want to explain CCAutoreleasePool It is called self active release pool , stay CCPoolManager ( Actively release the pool management class by yourself ) We have a member variable in the class CCArray * m_pReleasePoolStack; This is to actively release the pool stack , Inside the store CCAutoreleasePool Example .
CCAutoreleasePool There's a CCArray * m_pManagedObjectArray, This is an internal array of objects .
In general, their relationship is like this . Every time we actively manage objects by ourselves , It will be added to the memory free pool , You might ask , We don't release this thing , When will it be released , The answer is to release every frame cycle . And create a self active release pool again .
Let's see mainLoop Code
void CCPoolManager::pop()
{
if (! m_pCurReleasePool)
{
return;
}
int nCount = m_pReleasePoolStack->count();
m_pCurReleasePool->clear(); // Look here, everyone . This means that the memory pool is empty , We should see how he empties
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);// Here we initialize the memory pool again in a new frame
}
/*m_pCurReleasePool = NULL;*/
}
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);// This means that the sign of self active management becomes 0 了
//(*it)->release();
//delete (*it);
#ifdef _DEBUG
nIndex--;
#endif
}
m_pManagedObjectArray->removeAllObjects();
}
}It's probably like this , We imagine assuming that we are simply create A manager , I didn't hang it on the rendering tree , Our citation count must be 1 ah , And then through the reduction of their own active release pool . Will be released .
Case one :
CCScene *pscene = CCScene::create(); // The reference count is 1, Default internally autorelease 了
.
.
. After the frame cycle, the stack is cleared , Quote minus one ,pscene He was killed .
Another situation :
CCScene *pscene = CCScene::create(); // The reference count is 1. Default internally autorelease 了
addChild(pscene);// The reference count is 2.
.
.
.
After a frame cycle of stack clearing , Quote minus one . The reference count becomes 1. And next time, I won't actively release myself into the pool . So this spirit can always be on the rendering tree , When do we want to delete him . Maybe you want to release this “ spirit ”, We still need to call it manually release. Or call it autorelease Method .
Let me make a summary , Well, that's it , Let's have one CCObject It's running autorelease Method , The active release pool will be given to us by default at the beginning of the next frame cycle -1, Because we managed . Theoretically , Suppose the reference count is zero after subtracting one , It is what we should release , But we trust the engine , The engine will be duty bound to help us release it .
Suppose we not only created it ourselves , It is also added to the rendering tree . It means that we will continue to use this spirit , If you actively release the pool, you will reduce the reference count by one to one , The engine will know that you are creat You are still using this spirit , I don't care , Keep him alive , I still have to clean up my active release pool . Because I want to prepare for this frame cycle .
I unconsciously wrote this point . Originally, I still wanted to say a little more , Brush your teeth and go to bed early , Today, this really makes my day dark . The sun gave forth no more of its light , I understand . I just didn't convert my thoughts , At first, I didn't understand why I was so released , Later I learned . We should have done this . But sometimes these are registration functions , Interrupt function and so on , We don't know when to do , So let the engine do it , Because he knows how to do .
Brush one's teeth , sleep , Good night, everyone .......
.
.
Publisher : Full stack programmer stack length , Reprint please indicate the source :https://javaforall.cn/116441.html Link to the original text :https://javaforall.cn
边栏推荐
猜你喜欢

Helix QAC 2020.2 new static test tool maximizes the coverage of standard compliance

OneSpin | 解决IC设计中的硬件木马和安全信任问题

Small guide for rapid formation of manipulator (12): inverse kinematics analysis

Intelligent software analysis platform embold

Helix QAC 2020.2新版静态测试工具,最大限度扩展了标准合规性的覆盖范围
Mysql子查询关键字的使用方式(exists)

AADL Inspector 故障树安全分析模块

How to meet the dual needs of security and confidentiality of medical devices?

ERROR: 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your

Tensorflow2. How to run under x 1 Code of X
随机推荐
浅解ARC中的 __bridge、__bridge_retained和__bridge_transfer
现在网上开户安全么?想知道我现在在南宁,到哪里开户比较好?
微服务远程Debug,Nocalhost + Rainbond微服务开发第二弹
FTP steps for downloading files from Huawei CE switches
恶魔奶爸 指南帖——简易版
国家正规的股票交易app有哪些?使用安不安全
DataTable数据转换为实体
margin 等高布局
Helix QAC 2020.2 new static test tool maximizes the coverage of standard compliance
MinGW MinGW-w64 TDM-GCC等工具链之间的差别与联系「建议收藏」
ISO 26262 - 基于需求测试以外的考虑因素
Codesonar Webinar
Apifox interface integrated management new artifact
I have to use my ID card to open an account. Is the bank card safe? I don't understand it
Referrer和Referrer-Policy简介
POJ 3140 contents division "suggestions collection"
Klocwork 代码静态分析工具
CodeSonar通过创新型静态分析增强软件可靠性
Details of C language integer and floating-point data storage in memory (including details of original code, inverse code, complement, size end storage, etc.)
私募基金在中国合法吗?安全吗?