[√]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,触发了这个断言,也就暴漏了这个问题。

目录
相关文章
|
7月前
|
编译器 API C++
[√]vld编译Release遇到的各种问题
[√]vld编译Release遇到的各种问题
48 0
|
7月前
|
Android开发 iOS开发
[√]cocos2dx 内存泄露
[√]cocos2dx 内存泄露
46 0
|
7月前
|
算法 Java API
AJDK 8.0.0 Release Notes
AJDK 8.0.0 Release Notes
60 0
|
7月前
|
缓存 安全 Java
[√]cocos2dx 垃圾回收机制
[√]cocos2dx 垃圾回收机制
79 0
|
7月前
|
JavaScript C++
[√]cocos creator 热更新源码剖析(1)
[√]cocos creator 热更新源码剖析
69 1
|
7月前
|
JavaScript C++
[√]cocos creator 热更新源码剖析(2)
[√]cocos creator 热更新源码剖析(2)
32 1
|
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) 解决办法
532 0
QT creator中Debug、Profile、Release的区别
QT creator中Debug、Profile、Release的区别
351 0
|
网络协议 网络安全 C语言
NETMF Versions 4.1 Release 发布
NETMF Versions 4.1 Release 发布
656 0
|
容器
CloudProvider Release Notes
阿里云容器服务 CloudProvider release notes 2018-06-25 支持service.beta.kubernetes.io/alicloud-loadbalancer-backend-labelannotation让用户能够根据node的标签来指定SLB挂载哪些节点作为后端。
3320 0

热门文章

最新文章