#include "CCAutoreleasePool.h"
#include "ccMacros.h" NS_CC_BEGIN static CCPoolManager* s_pPoolManager = NULL; CCAutoreleasePool::CCAutoreleasePool(void)
{
m_pManagedObjectArray = new CCArray();
m_pManagedObjectArray->init();
} CCAutoreleasePool::~CCAutoreleasePool(void)
{
CC_SAFE_DELETE(m_pManagedObjectArray);
} void CCAutoreleasePool::addObject(CCObject* pObject)//添加对象,再释放一次,对象的引用为1
{
m_pManagedObjectArray->addObject(pObject);//1+1 CCAssert(pObject->m_uReference > , "reference count should be greater than 1");
++(pObject->m_uAutoReleaseCount);
pObject->release(); // -1
} void CCAutoreleasePool::removeObject(CCObject* pObject)
{
for (unsigned int i = ; i < pObject->m_uAutoReleaseCount; ++i)
{
m_pManagedObjectArray->removeObject(pObject, false);
}
} void CCAutoreleasePool::clear()//清理上帧自动管理的对象(每个obj的引用-1)
{
if(m_pManagedObjectArray->count() > )
{
//CCAutoreleasePool* pReleasePool;
#ifdef _DEBUG
int nIndex = m_pManagedObjectArray->count() - ;
#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();
}
} //--------------------------------------------------------------------
//
// CCPoolManager
//
//-------------------------------------------------------------------- CCPoolManager* CCPoolManager::sharedPoolManager()
{
if (s_pPoolManager == NULL)
{
s_pPoolManager = new CCPoolManager();
}
return s_pPoolManager;
} void CCPoolManager::purgePoolManager()
{
CC_SAFE_DELETE(s_pPoolManager);
} CCPoolManager::CCPoolManager()//m_pReleasePoolStack 用于储存 CCAutoreleasePool
{
m_pReleasePoolStack = new CCArray();
m_pReleasePoolStack->init();
m_pCurReleasePool = ;
} CCPoolManager::~CCPoolManager()
{ finalize(); // we only release the last autorelease pool here
m_pCurReleasePool = ;
m_pReleasePoolStack->removeObjectAtIndex(); CC_SAFE_DELETE(m_pReleasePoolStack);
} void CCPoolManager::finalize()
{
if(m_pReleasePoolStack->count() > )
{
//CCAutoreleasePool* pReleasePool;
CCObject* pObj = NULL;
CCARRAY_FOREACH(m_pReleasePoolStack, pObj)
{
if(!pObj)
break;
CCAutoreleasePool* pPool = (CCAutoreleasePool*)pObj;
pPool->clear();
}
}
} void CCPoolManager::push()//创建一个 m_pCurReleasePool 添加到 m_pReleasePoolStack
{
CCAutoreleasePool* pPool = new CCAutoreleasePool(); //ref = 1
m_pCurReleasePool = pPool; m_pReleasePoolStack->addObject(pPool); //ref = 2 pPool->release(); //ref = 1
} void CCPoolManager::pop()//每帧执行一次,如果 m_pReleasePoolStack 有则开始清理。
{
if (! m_pCurReleasePool)
{
return;
} int nCount = m_pReleasePoolStack->count(); m_pCurReleasePool->clear(); if(nCount > )
{
m_pReleasePoolStack->removeObjectAtIndex(nCount-); // if(nCount > 1)
// {
// m_pCurReleasePool = m_pReleasePoolStack->objectAtIndex(nCount - 2);
// return;
// }
m_pCurReleasePool = (CCAutoreleasePool*)m_pReleasePoolStack->objectAtIndex(nCount - );
} /*m_pCurReleasePool = NULL;*/
} void CCPoolManager::removeObject(CCObject* pObject)
{
CCAssert(m_pCurReleasePool, "current auto release pool should not be null"); m_pCurReleasePool->removeObject(pObject);
} void CCPoolManager::addObject(CCObject* pObject)
{
getCurReleasePool()->addObject(pObject);
} CCAutoreleasePool* CCPoolManager::getCurReleasePool()//获取本帧的 m_pCurReleasePool ,每帧的m_pCurReleasePool都是新的(因为被清了)
{
if(!m_pCurReleasePool)
{
push();
} CCAssert(m_pCurReleasePool, "current auto release pool should not be null"); return m_pCurReleasePool;
} NS_CC_END

大致思路就是:有CCPoolManager  与CCAutoreleasePool

程序是按帧,一帧一帧运行的

每帧执行的程序创建的obj如果使用了autorelease(CCObject的)会将obj添加到CCAutoreleasePool,这个在本帧惟一的,CCAutoreleasePool会被添加到CCPoolManager

每次mainLoop会执行内存清理(CCPoolManager的pop) 对上一帧保存的对象release 。也可以说是CCPoolManager 删除上次的CCAutoreleasePool。 如果上一帧的对象引用为1(初始为1)就会被释放掉。大于1不会被释放,但也不会再管了。

如果obj被添加到CCAutoreleasePool obj的m_uAutoReleaseCount会+1,直到从CCAutoreleasePool删除时-1.

cocos 自动内存管理分析的更多相关文章

  1. 垃圾回收算法手册:自动内存管理的艺术 BOOK

    垃圾回收算法手册:自动内存管理的艺术 2016-03-18 华章计算机 内容简介 PROSPECTUS 本书是自动内存管理领域的里程碑作品,汇集了这个领域里经过50多年的研究沉积下来的最佳实践,包含当 ...

  2. JVM自动内存管理机制——Java内存区域(下)

    一.虚拟机参数配置 在上一篇<Java自动内存管理机制——Java内存区域(上)>中介绍了有关的基础知识,这一篇主要是通过一些示例来了解有关虚拟机参数的配置. 1.Java堆参数设置 a) ...

  3. [深入理解Java虚拟机]<自动内存管理>

    Overview 走近Java:介绍Java发展史 第二部分:自动内存管理机制 程序员把内存控制的权利交给了Java虚拟机,从而可以在编码时享受自动内存管理.但另一方面一旦出现内存泄漏和溢出等问题,就 ...

  4. JVM自动内存管理机制--读这篇就GO了

    之前看过JVM的相关知识,当时没有留下任何学习成果物,有些遗憾.这次重新复习了下,并通过博客来做下笔记(只能记录一部分,因为写博客真的很花时间),也给其他同行一些知识分享. Java自动内存管理机制包 ...

  5. 【深入理解Java虚拟机】自动内存管理机制——垃圾回收机制

      Java与C++之间有一堵有内存动态分配和垃圾收集技术所围成的"高墙",墙外面的人想进去,墙里面的人却想出来.C/C++程序员既拥有每一个对象的所有权,同时也担负着每一个对象生 ...

  6. 深入理解Java虚拟机(自动内存管理机制)

    文章首发于公众号:BaronTalk 书籍真的是常读常新,古人说「书读百遍其义自见」还是很有道理的.周志明老师的这本<深入理解 Java 虚拟机>我细读了不下三遍,每一次阅读都有新的收获, ...

  7. JVM | 第1部分:自动内存管理与性能调优《深入理解 Java 虚拟机》

    目录 前言 1. 自动内存管理 1.1 JVM运行时数据区 1.2 Java 内存结构 1.3 HotSpot 虚拟机创建对象 1.4 HotSpot 虚拟机的对象内存布局 1.5 访问对象 2. 垃 ...

  8. iOS----ARC(自动内存管理)

    1.ARC是什么呢,有什么用? ARC是苹果官方推出的帮助我们苹果开发工程师管理内存的一种自动内存管理机制,它的前身是MRC,也就是手动内存管理: 2.ARC的基本原理是什么? ARC是编译器(时)特 ...

  9. cocos2d-x学习之自动内存管理

    一.自动内存管理 1)概述 C++语言默认是没有提供自动内存管理的.使用者需要自己分配,自己释放.在cocos2d-x里提供了一个自动内存管理的方案.主要是通过CCObject来提供的,用户只要继承了 ...

随机推荐

  1. js 字符与ASCII码互转

    将字符转为ASCII码 var str = "A"; str.charCodeAt(); var str1 = 'a'; str1.charCodeAt(); 将ASCII码转为字 ...

  2. MacBook上使用ssh localhost被拒绝

    最开始以为没有装sshd呢,实际上不是.又查了些方法,有些人居然把Linux上访问失败的方法直接照搬,让我建立公私钥.都没有成功.最后找到了解决方法,原来是由于苹果的安全限制,限制了这个功能. sud ...

  3. 解题:CF622F The Sum of the k-th Powers

    题面 TJOI2018出CF原题弱化版是不是有点太过分了?对,就是 TJOI2018 教科书般的亵渎 然而我这个问题只会那个题的范围的m^3做法 回忆一下1到n求和是二次的,平方求和公式是三次的,立方 ...

  4. c/c++ 大于等于 大于 时间效率比较

    变成汇编,都是: 大于等于和大于都是电路上的处理,时间上应该差不多.

  5. mybatis 的批量更新操作sql

    转: mybatis 的批量更新操作sql 2018年07月23日 10:38:19 海力布 阅读数:1689   版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.cs ...

  6. Codeforces Round #523 (Div. 2) B Views Matter

    传送门 https://www.cnblogs.com/violet-acmer/p/10005351.html 这是一道贪心题么???? 题意: 某展览馆展览一个物品,此物品有n堆,第 i 堆有a[ ...

  7. PHP生成四角图片

    <?php /** 圆角 $radius = 100; $img = imagecreatetruecolor($radius, $radius); // 创建一个正方形的图像 $bgcolor ...

  8. 让mysql监听ipv4

    系统:centos7 关闭ipv6方法: 方法1:编辑/etc/sysctl.conf文件,添加如下两行到文件 net.ipv6.conf.all.disable_ipv6 = 1 net.ipv6. ...

  9. Harbor 使用 Helm 一键安装

    安装 Harbor Harbor 支持多种安装方式,源码目录下面默认有一个安装脚本(make/install.sh),采用 docker-compose 的形式运行 Harbor 各个组件,和前面的课 ...

  10. JVM高手之路七(tomcat调优以及tomcat7、8性能对比)

         版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/lirenzuo/article/details/77164033 因为每个链路都会对其性能 ...