当前位置:网站首页>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
边栏推荐
- [matrix multiplication] [noi 2012] [cogs963] random number generator
- How to meet the dual needs of security and confidentiality of medical devices?
- UVA 11080 – Place the Guards(二分图判定)
- openGl超级宝典学习笔记 (1)第一个三角形「建议收藏」
- C语言多角度帮助你深入理解指针(1. 字符指针2. 数组指针和 指针数组 、数组传参和指针传参3. 函数指针4. 函数指针数组5. 指向函数指针数组的指针6. 回调函数)
- 开户还得用身份证银行卡安全吗,我是小白不懂
- 使用枚举实现英文转盲文
- npm uninstall和rm直接删除的区别
- 死锁的产生条件和预防处理[通俗易懂]
- 【奖励公示】第22期 2022年6月奖励名单公示:社区明星评选 | 新人奖 | 博客同步 | 推荐奖
猜你喜欢
MySQL storage expression error

目标:不排斥 yaml 语法。争取快速上手
Klocwork 代码静态分析工具

恶魔奶爸 B3 少量泛读,完成两万词汇量+

Measure the height of the building

Optimization cases of complex factor calculation: deep imbalance, buying and selling pressure index, volatility calculation

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

软件缺陷静态分析 CodeSonar 5.2 新版发布

Don't fall behind! Simple and easy-to-use low code development to quickly build an intelligent management information system
![嵌入式系统真正安全了吗?[ OneSpin如何为开发团队全面解决IC完整性问题 ]](/img/af/61b384b1b6ba46aa1a6011f8a30085.png)
嵌入式系统真正安全了吗?[ OneSpin如何为开发团队全面解决IC完整性问题 ]
随机推荐
How to choose fund products? What fund is suitable to buy in July 2022?
神兵利器——敏感文件发现工具
阿洛的烦恼
如何满足医疗设备对安全性和保密性的双重需求?
智能交通焕发勃勃生机,未来会呈现哪些巨变?[通俗易懂]
Tensorflow2. How to run under x 1 Code of X
Lingyun going to sea | yidiantianxia & Huawei cloud: promoting the globalization of Chinese e-commerce enterprise brands
What are the official stock trading apps in the country? Is it safe to use
awk处理JSON处理
刚开户的能买什么股票呢?炒股账户安全吗
Details of C language integer and floating-point data storage in memory (including details of original code, inverse code, complement, size end storage, etc.)
使用高斯Redis实现二级索引
A brief understanding of the in arc__ bridge、__ bridge_ Retained and__ bridge_ transfer
You want to kill a port process, but you can't find it in the service list. You can find this process and kill it through the command line to reduce restarting the computer and find the root cause of
HOJ 2245 浮游三角胞(数学啊 )
Onespin | solve the problems of hardware Trojan horse and security trust in IC Design
AADL inspector fault tree safety analysis module
开户还得用身份证银行卡安全吗,我是小白不懂
Referrer和Referrer-Policy简介
Guava multithreading, futurecallback thread calls are uneven