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

目录
相关文章
|
网络协议 测试技术
PTS压测问题之如何确定压测可以停止
PTS(Performance Testing Service)是一项面向网站、应用等提供的压力测试服务,用于模拟不同场景下的用户访问,评估系统的性能表现;在进行PTS压测时,可能会出现一些异常或报错,本合集将PTS压测中频繁出现的问题及其解决办法进行汇编,旨在帮助用户更有效地进行性能测试和问题定位。
388 2
|
12月前
|
网络协议
深入解析:TCP四次挥手断开连接的全过程及必要性
在网络通信中,TCP(传输控制协议)以其可靠性和顺序保证而闻名。然而,TCP连接的建立和终止同样重要,它们确保了网络资源的有效管理和数据传输的完整性。本文将详细描述TCP连接的四次挥手过程,并探讨为何需要四次挥手来正确终止一个TCP连接。
388 2
|
存储 负载均衡 关系型数据库
|
存储 安全 网络安全
云计算浪潮之下,网络安全的航标与护盾
在数字时代的海洋中,云计算是推动企业航行的强大引擎。然而,随着数据量的激增和网络攻击的日益猖獗,网络安全成为维护信息安全的关键。本文将探讨云计算环境中的安全挑战,分析云服务供应商的安全责任,并介绍如何通过技术与策略相结合的方式,构建一个坚固的网络安全防护体系。
|
测试技术 uml
UML使用问题之如何在PlantUML中表示执行者与用例之间的关联
UML使用问题之如何在PlantUML中表示执行者与用例之间的关联
使用队列解决高并发下使用Client对象调用webService接口
使用队列解决高并发下使用Client对象调用webService接口
|
消息中间件 安全 Kafka
如何为Kafka加上账号密码(二)
本小节我们就为Kafka添加最简单的认证方式,也就是SASL_PLAINTEXT(即SASL/PLAIN+ 非加密通道)。
1781 5
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的农副产品销售网站的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的农副产品销售网站的详细设计和实现(源码+lw+部署文档+讲解等)
|
Shell 开发工具 计算机视觉
【vision transformer】DETR原理及代码详解(三)
【vision transformer】DETR原理及代码详解
323 0