[√]cocos2dx关于retain release

简介: [√]cocos2dx关于retain release

问题表现

游戏转换场景,对无用的纹理内存从TextureCache清理,在移除场景节点时,触发了_referenceCount>0的断言。

这个问题在window上没有复现,在Android上必现,Android触发断言时的调用堆栈如下:

image.png

可以看到经历了好几次的release,中间红框的是清理node.children的逻辑,最终出问题的release调用者是一个Texture2D,是一个Sprite在析构的时候,清理对应的Texture2D导致的问题,向上反推,通过log日志,可以得到关于Sprite和Texture2D的一些信息。

排查到这个问题就已经花了好长时间,中间有CC_SAFE_RELEASE(_texture);这个宏导致堆栈看不清,这也是一个坑。

lua_pcall 是来自lua层的调用,也就是说lua层有在调用node:release(),这个node在删除子节点的时候出现的问题,导致问题的根源是清理TextureCache导致的。

引用计数出现了0,意味着该对象已经被delete了,但是为啥会变成0呢?

可能得情况

Node* node1= new Node();// ref1
node1->release();// ref0
node1->release();// 触发断言

还有就是父子关系

Node* parent=new Node();// parent.ref=1
Node* child= new Node();// child.ref=1
parnet->addChild(child);// child.ref=2
parent->relese();// parent.ref=0

add

image.png

remove

image.png

当前帧结束,会清理auto release pool

image.png

windows的fill partter

在 Visual Studio 的 Debug 模式下,默认情况下,已释放的堆内存通常会被填充为 0xCC(即十六进制的 0xCC)。这个值被称为 "fill pattern",它有助于标识悬垂指针或访问已释放内存的错误。

unsigned int

  • debug 3722304989(0xDDDDDDDD)
  • release: 11552624
  • std::numeric_limits::max() 4294967295
预设值 说明
0xCC 上申请的,未初始化的变量,的缺省值,0xCC其实是INT3中断指令
0xCD 上申请的,未初始化的变量,的缺省值
0xDD 上申请的,所在空间释放后,的缺省值
0xFD 在已申请的堆区空间上,设定上下边界值

编译器在执行运行时检查 —— /RTCs, /RTCu, /RTC1,这些会在运行时候自动检查缓冲区溢出

问题定位

在清理TextureCache的时候,内部实现也是进行了一次release,图片纹理真的被释放掉了,此时这个纹理内存已经delete了!

当清理和这个图片有关联的Sprite的时候,Sprite也会清理对应的Texture,但是Sprite->Texture指向的是一块已经释放的内存,Sprite->Texture != nullptr,因为没人告诉Sprite置空纹理指针,虽然纹理内存被释放,但是仍旧可以访问,只是取到的值不可预期。

所以当再次访问纹理的release函数时,在window上_referenceCount可能是一个非常大的值,当然也就触发不了这个断言

void Ref::release(){
    CCASSERT(_referenceCount > 0, "release reference count should be greater than 0");
}

不过在Android上,发现_referenceCount为0,触发了这个断言,也就暴漏了这个问题。

目录
相关文章
|
编译器 API C++
[√]vld编译Release遇到的各种问题
[√]vld编译Release遇到的各种问题
82 0
|
Android开发 iOS开发
[√]cocos2dx 内存泄露
[√]cocos2dx 内存泄露
74 0
|
XML C++ 数据格式
[√]vld的安装和使用
[√]vld的安装和使用
123 0
|
iOS开发
you must have accepted the latest version of the IOS Developer Program Agreement
you must have accepted the latest version of the IOS Developer Program Agreement
73 0
you must have accepted the latest version of the IOS Developer Program Agreement
|
iOS开发
未解决:configure: error: XCode tool ‘metal‘ neither found in path nor with xcrunchecking for metal...
未解决:configure: error: XCode tool ‘metal‘ neither found in path nor with xcrunchecking for metal...
183 0
|
iOS开发
was built for newer iOS version (8.2) than being linked (8.0) 解决办法
was built for newer iOS version (8.2) than being linked (8.0) 解决办法
562 0
|
iOS开发 MacOS
Mac 解决 gyp: No Xcode or CLT version detected! 报错
Mac 解决 gyp: No Xcode or CLT version detected! 报错
301 0
QT creator中Debug、Profile、Release的区别
QT creator中Debug、Profile、Release的区别
399 0
|
网络协议 网络安全 C语言
NETMF Versions 4.1 Release 发布
NETMF Versions 4.1 Release 发布
677 0
|
iOS开发
This iPhone xxx is running iOS xxx, which may not be supported by this version of Xcode.
有时候我们的iPhone紧跟apple的步伐升级最新的版本了,但是Xcode并没有及时更新到最新版本(Xcode是在很大,而且有时候是需要最新的beta版本的),这时候真机调试的时候就会出现下面这样的问题: 报错: Could not locate device support files.
1789 0