ActionManager memory leak

cocos2d-x3.7


都3.7了还有这样的bug,真是好难过,不过还是好开源的,谁都可以贡献一下

问题描述:

当创建一个node,并让它run一个action的时,如果这个node没有添加到任何其它节点(即没有父节点),那么改node和action将一直不会被释放。


原因:

在node调用runAction时,会将动画交给ActionManager来管理,即调用ActionManager::addAction,看该函数的实现:

void ActionManager::addAction(Action *action, Node *target, bool paused)
{
//...
if (! element)
{
element = (tHashElement*)calloc(sizeof(*element), 1);
element->paused = paused;
target->retain(); //!!!watch out!!!
element->target = target;
HASH_ADD_PTR(_targets, target, element);
}
//...

注意这里会把node给retain一次,那它是在哪里release的呢,看下面:

void ActionManager::update(float dt)
{
//...
elt = (tHashElement*)(elt->hh.next);
if (_currentTargetSalvaged && _currentTarget->actions->num == 0)
{
deleteHashElement(_currentTarget);
}
//...
}
void ActionManager::deleteHashElement(tHashElement *element)
{
ccArrayFree(element->actions);
HASH_DEL(_targets, element);
element->target->release(); // release node
free(element);
}

也就是说,当一个node在运行一个action时会被retain(referenceCount+1),在action运行完成后就会被release(referenceCount-1)。这么看起来没什么问题,但是当这个node不在running状态时,即没有添加到任何节点,通过create创建下一帧应该被自动释放,如果这时候给它运行了一个动画(ActionManager::addAction时第三个参数paused为true),再看update函数:

void ActionManager::update(float dt)
{
if (! _currentTarget->paused) //动画不会被执行
{
//...
}
//...
elt = (tHashElement*)(elt->hh.next);
if (_currentTargetSalvaged && _currentTarget->actions->num == 0)
{
deleteHashElement(_currentTarget);
}
//...
}

此时动画一直不会执行,也就是说动画不会完成,那么actions->num不可能等于0,则该节点就一直不会被释放。


解决方法:

void ActionManager::update(float dt)
{
//...
elt = (tHashElement*)(elt->hh.next);
if (_currentTargetSalvaged && _currentTarget->actions->num == 0)
{
deleteHashElement(_currentTarget);
}
//if some node refrence 'target', it's refrence count >= 2 (issues #14050)
else if (_currentTarget->target->getReferenceCount() == 1)
{
deleteHashElement(_currentTarget);
}
//...
}

那么问题来了:为什么会有这样的行为呢——创建一个node,不加到任何节点,还给它run一个action?

这里解释过一遍了:https://github.com/cocos2d/cocos2d-x/pull/14090

cocos2dx - ActionManager内存泄露的更多相关文章

  1. cocos2d-x 从onEnter、onExit、 引用计数 谈内存泄露问题

    /////////////////////////////////// //author : zhxfl //date   : 2013.8.29 //email  : 291221622@qq.co ...

  2. quick cocos2dx lua 内存释放

    前言 对于内存的优化,网上有很多例子和教程.总体来说,就那么几种解决方案,在最后我会简单提下,这里先说下在quick中,对于图片的处理. 1.查看内存调试信息 对于quick框架的了解,我们可以参考\ ...

  3. cocos2d-x之内存管理(4)

    c++的内存管理一直以来都是个问题,也有多种实现方案,比如智能指针,使用引用计数等,cocos2d-x也需要涉及到内存的管理. cocos2d-x是如何管理内存的呢? cocos2d-x的内存管理主要 ...

  4. cocos2dx的内存管理机制

    首先我们必须说一下c++中变量的内存空间的分配问题,我们在c++中写一个类,可以在栈上分配内存空间也可以使用new在堆上分配内存空间,如果类对象是在栈上分配的内存空间,这个内存空间的管理就不是我们的事 ...

  5. 引用计数的cocos2dx对象内存管理和直接new/delete box2d对象内存管理冲突的解决方法

    转载请注明: http://blog.csdn.net/herm_lib/article/details/9316601 项目中用到了cocos2dx和box2d,cocos2dx的内存是基于引用计数 ...

  6. java: web应用中不经意的内存泄露

    前面有一篇讲解如何在spring mvc web应用中一启动就执行某些逻辑,今天无意发现如果使用不当,很容易引起内存泄露,测试代码如下: 1.定义一个类App package com.cnblogs. ...

  7. 查看w3wp进程占用的内存及.NET内存泄露,死锁分析

    一 基础知识 在分析之前,先上一张图: 从上面可以看到,这个w3wp进程占用了376M内存,启动了54个线程. 在使用windbg查看之前,看到的进程含有 *32 字样,意思是在64位机器上已32位方 ...

  8. C++11 shared_ptr 智能指针 的使用,避免内存泄露

    多线程程序经常会遇到在某个线程A创建了一个对象,这个对象需要在线程B使用, 在没有shared_ptr时,因为线程A,B结束时间不确定,即在A或B线程先释放这个对象都有可能造成另一个线程崩溃, 所以为 ...

  9. 基于HTML5的WebGL应用内存泄露分析

    上篇(http://www.hightopo.com/blog/194.html)我们通过定制了CPU和内存展示界面,体验了HT for Web通过定义矢量实现图形绘制与业务数据的代码解耦及绑定联动, ...

随机推荐

  1. UVa 1349 - Optimal Bus Route Design(二分图最佳完美匹配)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  2. webstorm&phpstorm打开大型项目卡死解决如vue-laravel-Yii2

    用phpstorm开发时如果项目中文件过多会造成phpstorm变慢甚至卡死,尤其在node加入到我们的项目中更加会加重这种情况,因为node_modules目录中的模块非常多,phpstorm加载这 ...

  3. The Android ION memory allocator

    http://lwn.net/Articles/480055/ Back in December 2011, LWN reviewed the list of Android kernel patch ...

  4. ASP.NET教程

    1.ASP.NET是一个使用Html Css JavaScript和服务器脚本创建网页和网站的开发框架 2.ASP.NET支持三种开发模式:WebPages(Web页面).MVC(Model View ...

  5. 用javascript编写猜拳游戏(函数)

    const readline = require('readline-sync')//引用readline-sync console.log('欢迎进入猜拳游戏'); //电脑随机出拳 let fn ...

  6. 深入浅出爬虫之道: Python、Golang与GraphQuery的对比

    深入浅出爬虫之道: Python.Golang与GraphQuery的对比 本文将分别使用 Python ,Golang 以及 GraphQuery 来解析某网站的 素材详情页面 ,这个页面的特色是具 ...

  7. Xdebug 备注

    安装步骤: 查看自己的环境是否已安装 Xdebug ,查看方法:使用phpinfo(),搜索 Xdebug 如果没有 如图: 如果没有:下一步确定你的PHP版本信息: Xdebug下载地址 https ...

  8. SQL Server公用表达式CET递归查询所有上级数据

    with cte as( select bianma,fjbm from #tree where chkDisabled='true' union all select t.bianma,t.fjbm ...

  9. JSP/Servlet开发——第八章 JSTL和EL

    1. EL表达式: ●需要EL表达式的原因: ◆在JSP中使用Java脚本的局限: 1).在JSP页面中嵌入大量的Java代码: 2).访问结构比较复杂的数据时代码烦琐,且经常需要强制类型转换: eg ...

  10. MySQL 半同步重要状态参数说明

    如果配置了MySQL半同步复制,可以在主库查询半同步状态,命令为: SHOW GLOBAL STATUS LIKE '%semi%'; 参数说明      Rpl_semi_sync_master_c ...