当前位置:网站首页>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
边栏推荐
猜你喜欢
Codesonar enhances software reliability through innovative static analysis

95年专注安全这一件事 沃尔沃未来聚焦智能驾驶与电气化领域安全
![[paper reading] maps: Multi-Agent Reinforcement Learning Based Portfolio Management System](/img/76/b725788272ba2dcdf866b28cbcc897.jpg)
[paper reading] maps: Multi-Agent Reinforcement Learning Based Portfolio Management System

Cantata9.0 | 全 新 功 能

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

CodeSonar网络研讨会

Ubuntu安装mysql8遇到的问题以及详细安装过程

神兵利器——敏感文件发现工具

Intelligent software analysis platform embold

AADL inspector fault tree safety analysis module
随机推荐
Differences and connections between MinGW, mingw-w64, tdm-gcc and other tool chains "suggestions collection"
[award publicity] issue 22 publicity of the award list in June 2022: Community star selection | Newcomer Award | blog synchronization | recommendation Award
Details of C language integer and floating-point data storage in memory (including details of original code, inverse code, complement, size end storage, etc.)
特征生成
201215-03-19—cocos2dx内存管理–具体解释「建议收藏」
gridView自己定义做时间排版「建议收藏」
OneSpin 360 DV新版发布,刷新FPGA形式化验证功能体验
easyui 日期控件清空值
数值法求解最优控制问题(〇)——定义
AADL Inspector 故障树安全分析模块
凌云出海记 | 赛盒&华为云:共助跨境电商行业可持续发展
寫一下跳錶
Validutil, "Rethinking the setting of semi supervised learning on graphs"
The latest version of codesonar has improved functional security and supports Misra, c++ parsing and visualization
Helix QAC 2020.2 new static test tool maximizes the coverage of standard compliance
Codeforces 474 F. Ant colony
最新版本的CodeSonar改进了功能安全性,支持MISRA,C ++解析和可视化
【函数递归】简单递归的5个经典例子,你都会吗?
awk处理JSON处理
华泰证券可以做到万一佣金吗,万一开户安全嘛