#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. TimerTask的run()方法里面如何调用service层里面的方法

    在java的spring框架中,用Timer和TimerTask来实现定时任务,有时我们要在TimerTask的子类的重写run方法里,调用service层的方法. 但是不管是spring.xml配置 ...

  2. docker 使用指南

    Compose is a tool for defining and running multi-container Docker applications. With Compose, you us ...

  3. Django(十九)Ajax全套

    参考博客:http://www.cnblogs.com/wupeiqi/articles/5703697.html 提交: - Form - Ajax 一.Ajax,偷偷向后台发请求 - XMLHtt ...

  4. 斯坦福大学公开课机器学习:advice for applying machine learning | learning curves (改进学习算法:高偏差和高方差与学习曲线的关系)

    绘制学习曲线非常有用,比如你想检查你的学习算法,运行是否正常.或者你希望改进算法的表现或效果.那么学习曲线就是一种很好的工具.学习曲线可以判断某一个学习算法,是偏差.方差问题,或是二者皆有. 为了绘制 ...

  5. pycharm更新之后pip显示没有main

    更新pip之后,Pycharm安装package出现报错:module 'pip' has no attribute 'main' 找到安装目录下 helpers/packaging_tool.py文 ...

  6. SVN YUM安装

    一,安装: yum install subversion 二,创建配置SVN仓库: 目录自定,我这是在/home下: #cd /home # mkdir svn #svnadmin create /h ...

  7. vue init 解决办法

    /由于windows系统的某方面问题,vue脚手架安装可能会出现第一证书丢失 // 报错:vue-cli · Failed to download repo vuejs-templates/webpa ...

  8. Redis分布式锁----悲观锁实现,以秒杀系统为例

    摘要:本文要实现的是一种使用redis来实现分布式锁. 1.分布式锁 分布式锁在是一种用来安全访问分式式机器上变量的安全方案,一般用在全局id生成,秒杀系统,全局变量共享.分布式事务等.一般会有两种实 ...

  9. 2017-12-15python全栈9期第二天第三节之作业讲解用户三次登陆

    #!/user/bin/python# -*- coding:utf-8 -*-i = 0while i < 3: username = input('请输入账号:') password = i ...

  10. centos 7.2 部署并升级gitlab

    事由: 老git服务器centos 7.2上的git版本是8.13.5,先特在一台测试机centos 7.2上安装git 8.13.5 后,还原git后,在对测试服务器上git进行升级操作. 测试服务 ...