cocos2dx - ActionManager内存泄露
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内存泄露的更多相关文章
- cocos2d-x 从onEnter、onExit、 引用计数 谈内存泄露问题
/////////////////////////////////// //author : zhxfl //date : 2013.8.29 //email : 291221622@qq.co ...
- quick cocos2dx lua 内存释放
前言 对于内存的优化,网上有很多例子和教程.总体来说,就那么几种解决方案,在最后我会简单提下,这里先说下在quick中,对于图片的处理. 1.查看内存调试信息 对于quick框架的了解,我们可以参考\ ...
- cocos2d-x之内存管理(4)
c++的内存管理一直以来都是个问题,也有多种实现方案,比如智能指针,使用引用计数等,cocos2d-x也需要涉及到内存的管理. cocos2d-x是如何管理内存的呢? cocos2d-x的内存管理主要 ...
- cocos2dx的内存管理机制
首先我们必须说一下c++中变量的内存空间的分配问题,我们在c++中写一个类,可以在栈上分配内存空间也可以使用new在堆上分配内存空间,如果类对象是在栈上分配的内存空间,这个内存空间的管理就不是我们的事 ...
- 引用计数的cocos2dx对象内存管理和直接new/delete box2d对象内存管理冲突的解决方法
转载请注明: http://blog.csdn.net/herm_lib/article/details/9316601 项目中用到了cocos2dx和box2d,cocos2dx的内存是基于引用计数 ...
- java: web应用中不经意的内存泄露
前面有一篇讲解如何在spring mvc web应用中一启动就执行某些逻辑,今天无意发现如果使用不当,很容易引起内存泄露,测试代码如下: 1.定义一个类App package com.cnblogs. ...
- 查看w3wp进程占用的内存及.NET内存泄露,死锁分析
一 基础知识 在分析之前,先上一张图: 从上面可以看到,这个w3wp进程占用了376M内存,启动了54个线程. 在使用windbg查看之前,看到的进程含有 *32 字样,意思是在64位机器上已32位方 ...
- C++11 shared_ptr 智能指针 的使用,避免内存泄露
多线程程序经常会遇到在某个线程A创建了一个对象,这个对象需要在线程B使用, 在没有shared_ptr时,因为线程A,B结束时间不确定,即在A或B线程先释放这个对象都有可能造成另一个线程崩溃, 所以为 ...
- 基于HTML5的WebGL应用内存泄露分析
上篇(http://www.hightopo.com/blog/194.html)我们通过定制了CPU和内存展示界面,体验了HT for Web通过定义矢量实现图形绘制与业务数据的代码解耦及绑定联动, ...
随机推荐
- chromedriver链接
http://npm.taobao.org/mirrors/chromedriver/
- Linux系统中while管道的
因为项目从AIX系统迁移到了RedHat系统,之前写过的一段Shell脚本不能成功运行,经过分析,锁定了关键代码如下: readFileContent(){ currentFile=$ fileSho ...
- PHP代码的多继承 -》 PHP代码复用新的姿势 trait
本文参考: http://php.net/language.oop5.traits 一.什么是trait 从PHP 5.4.0 开始 PHP 实现了一种新的代码复用方式 trait. 二.trait ...
- [转]MFC子线程更改图像数据后更新主窗口图像显示方法
程序思路是由外部的输入输出控制卡发出采集图像信号,之后相机采集图像得到图像数据指针,接收图像数据指针创建成图像最后显示到MFC对话框应用程序的Picture Control控件上,同时,为了标定相机位 ...
- Apple的UIAutomation环境搭建和入门知识
简述 Xcode的instruments中的Automation是为了实现自动化测试的一个工具.实现方式有两种:它提供了两种实现方式, 1) 是通过JS脚本语言来执行自动化测试(普通自动化测试 ...
- 使用canvas输出base64_url
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 架构模式:MVC与MVVM
本文探讨如下几个问题: 什么是MVC 什么是MVVM MVC与MVVM对架构属性的影响 MVC实例SpringMVC MVVM实例Vue MVC.MVVM与Layer中的Model,Controlle ...
- JAVA并发-线程状态
一.线程基本状态 新建:线程已创建但start()方法还没执行 就绪(可运行):start()方法已运行,但还没被选择 运行:从就绪线程中选择出某一个线程进行run()操作 阻塞(不可运行):线程正在 ...
- python基础 列表和字符串
1.列表和字符串最大区别就是 列表可以改变,字符串不可以改变 列表: welldone = [ "hutu","python","java" ...
- c/c++面试指导---c语法总结
任何一门学科或者专业在学习的过程中都要把握总结框架,大家在面试c/c++职位过程中要应对各种企业的面试,回答企业面试官的各种技术问题.如何应对各种各样的关于c/c++的企业面试题目,从各种繁杂的题目中 ...