当前位置: 首页 > news >正文

creator-泄漏检测之资源篇


title: creator-泄漏检测之资源篇
categories: Cocos2dx
tags: [creator, 优化, 泄漏, 内存]
date: 2023-03-29 14:48:48
comments: false
mathjax: true
toc: true

creator-泄漏检测之资源篇


前篇

  • 资源释放 - https://docs.cocos.com/creator/manual/zh/asset/release-manager.html

  • 执行相关测试打快照前, 一定要多 gc js 几次

    image-20230329152312826


相关 dump 信息的代码

  • dump

    public dumpPath(path: string) {let bundleName = "resources"let bundle = assetManager.getBundle(bundleName);let asset01 = bundle.get(path);let uuid = asset01._uuidthis.dumpUuidRecur(uuid)
    }private dumpUuidRecur(uuid: string, depth: number = 1) {let pre = "---".repeat(depth)var asset01 = assetManager.assets.get(uuid)!;var uuids: string[] = assetManager.dependUtil.getDepsRecursively(uuid)!;LogUtil.D(`${pre} dumpUuidRecur: ${uuid}, refCnt: ${asset01.refCount}\nasset:`, asset01, "\nuuid:", uuids)uuids.forEach(uuid => {this.dumpUuidRecur(uuid, ++depth)});
    }public dump() {assetManager.assets.forEach((value: Asset, key: string) => {console.log(assetManager.assets.get(key));})console.log(`当前资源总数:${assetManager.assets.count}`);
    }

静态加载: 多个预制引用同一张图

  1. 制作了两个最简单的预制, 里面引用同一个图片

    image-20230329145021401

  2. 运行动态 load 出来

  3. 查看一下这两个预制路径的资源信息

    image-20230329145353550

    • 发现 spriteFrame 就有维护引用计数, texture2d 和 imageAsset 就没维护引用计数

      根据管饭文档: https://docs.cocos.com/creator/manual/zh/asset/release-manager.html#%E8%B5%84%E6%BA%90%E7%9A%84%E9%9D%99%E6%80%81%E5%BC%95%E7%94%A8

      我们只需要维护 预制的引用计数 -1, 引擎会去维护 spriteFrame 引用技术, 进而维护 texture2d 和 imageAsset, spriteFrame 就相当于右图中的 Material

      image-20230329145540060


销毁预制时引用计数 -1

  1. 未加载 预制情况下, 总数量是 55

    image-20230329145900957

  2. 加载 预制情况下, 总数量是 60

    image-20230329145917606

  3. 销毁预制, 并且预制引用计数-1, 总数量回到 55
    资源正常

    image-20230329145937661


动态加载: 正确

  1. 未加载 预制情况下, 总数量是 55

    image-20230329150045997

  2. 加载预制后, 在动态加载一张 big002 的图片并且引用计数+1, 总数 63

    image-20230329150122949

  3. 销毁预制, 并且预制引用计数-1, 并且将动态加载出来的资源引用计数-1, 总数量回到 55
    资源正常

    !!!这里很关键的就是要自己去维护 动态加载的资源的 引用计数!!!

    image-20230329150147216


动态加载: 错误

  1. 未加载 预制情况下, 总数量是 55

    image-20230329150301368

  2. 加载预制后, 在动态加载一张 big002 的图片 (不操作引用计数), 总数 63

    image-20230329150322070

  3. 销毁预制, 总数量没有回到 55
    资源不正常

    image-20230329150345262

    看到 big002 spriteFrame 引用计数虽然为 0, 但是为什么还没释放呢? 导致关联的 texture2d 和 imageAsset 也没有被释放

    cocos 触发是放是由 decRef 减引用计数的方法里触发, 所有还是需要手动调用, 才能进行释放

    • 3.7.1 相关源码

      image-20230329150427482


资源追踪自动维护引用计数

摸清了释放规则后, 就可以在自定义的资源管理器中, 加入一个 追踪器, 让加载出来的资源, 根据 节点 的生命周期结束时, 自动去维护相关加载出来的资源, 让开发人员不用去关心引用计数问题, 只关心节点的生成和销毁

  1. 其实原理很简单, 就是在加载出来时往 节点 身上挂个组件去记录资源, 从而维护引用计数.

    • AssetTracker.ts

      import { _decorator, Component, Node, Asset, SpriteFrame } from 'cc';
      import { LogUtil } from '../log/LogUtil';
      const { ccclass, property } = _decorator;@ccclass('AssetTracker')
      export class AssetTracker extends Component {public static trace(go: Node, ast: Asset) {let at = go.getComponent(AssetTracker)if (!at) {at = go.addComponent(AssetTracker)}at.traceInner(ast)}private _astArr = new Array<Asset>()traceInner(ast: Asset) {ast.addRef()this._astArr.push(ast)}onDestroy() {// LogUtil.D(`--- onDestroy, cnt: ${this._astArr.length}, _astArr:\n`, this._astArr)this._astArr.forEach((ast, idx, arr) => {ast.decRef()})this._astArr = null}debugDump() {this._astArr.forEach((ast, idx, arr) => {LogUtil.D("", ast)})}
      }
      
  2. 相关加载接口示例

    // ------------------------------------ 对外接口 begin
    public async instantiateAsync(prefabPath: string, parent?: Node) {return new Promise<Node>((resolve) => {this.load(prefabPath, (err: Error, asset: Prefab) => {if (err) {LogUtil.E(`--- instantiateAsync error, path: ${prefabPath}, err:`, err)resolve(null)return}let go = instantiate(asset);AssetTracker.trace(go, asset) // 资源计数追踪if (parent)go.parent = parentresolve(go)})})
    }// refGo 挂点, 最好是资源要依附的节点
    public async loadAssetAsync<T extends Asset>(assetPath: string, refGo: Node) {return new Promise<T>((resolve) => {this.load(assetPath, (err: Error, asset: T) => {if (err) {LogUtil.E(`--- loadAssetAsync error, path: ${assetPath}, err:`, err)resolve(null)return}AssetTracker.trace(refGo, asset) // 资源计数追踪resolve(asset)})})
    }// refGo 挂点, 最好是资源要依附的节点
    public async loadRemoteAsync<T extends Asset>(url: string, opts: IRemoteOptions, refGo: Node) {return new Promise<T>((resolve) => {this.loadRemote(url, opts, (err: Error, asset: T) => {if (err) {LogUtil.E(`--- loadRemoteAsync error, url: ${url}, err:`, err)resolve(null)return}AssetTracker.trace(refGo, asset) // 资源计数追踪resolve(asset)})})
    }
    // ------------------------------------ 对外接口 end
    

实测

  1. 未加载 预制情况下, 总数量是 55, 内存和图片缓存如下

    image-20230329152013866

  2. 加载 预制 并且动态加载 图片 情况下, 总数量是 61, 内存和图片缓存如下

    image-20230329152036689

  3. 销毁预制节点, 总数量回到 55, 内存和图片缓存也回到了初始值, 说明正常释放资源

    image-20230329152054504


相关文章:

creator-泄漏检测之资源篇

title: creator-泄漏检测之资源篇 categories: Cocos2dx tags: [creator, 优化, 泄漏, 内存] date: 2023-03-29 14:48:48 comments: false mathjax: true toc: true creator-泄漏检测之资源篇 前篇 资源释放 - https://docs.cocos.com/creator/manual/zh/asset/release-manager…...

【DevOps】Jenkins 运行任务时遇到 FATAL:Unable to produce a script file 报错(已解决)

文章目录一、问题描述二、定位原因三、解决方案四、其他方案五、总结关键词&#xff1a; Jenkins、Unable to produce a script file、UnmappableCharacterException、IOException: Failed to create a temp file on一、问题描述 由于使用的 Jenkins 存在安全漏洞&#xff08;…...

Web前端

WEB前端 HTMLCSSJavaScriptjQuery(js框架)Bootstrap(CSS框架)AJAXJSON 文章目录 WEB前端WEB前端三大核心技术Web开发工具文本编辑器集成开发环境(IDE)浏览器选择HTML什么是 HTML?HTML版本变迁HTML-HelloWorldHTML 文档 = 网页HTML 标签属性(Attribute)HTML 常用标签...

资源操作:Resources

文章目录1. Spring Resources概述1.2 Resource 接口1.3 Resource的实现类1.3.1 UrlResource访问网络资源1.3.2 ClassPathResource访问类路径下资源1.3.3 FileSystemResource访问文件系统资源1.3.4 ServletContextResource1.3.5、InputStreamResource1.3.6、ByteArrayResource1.…...

GDB调试的学习

很早就想在好好学一学gdb了&#xff0c;正好最近学算法&#xff08;以前一直以为干硬件不需要什么特别厉害的算法&#xff0c;结果现在卷起来了。大厂面试题也有复杂一些的算法了&#xff09; 下面的这些命令是别的博主总结的 GDB 调试过程_gdb调试过程_麷飞花的博客-CSDN博客…...

熵值法综合评价分析流程

熵值法综合评价分析流程 一、案例背景 当前有一份数据&#xff0c;是各品牌车各个维度的得分情况&#xff0c;现在想要使用熵值法进行综合评价&#xff0c;得到各品牌车的综合得分&#xff0c;从而进行车型优劣对比&#xff0c;为消费者提供购车依据。 数据如下&#xff08;数…...

使用Python Pandas库操作Excel表格的技巧

在数据分析和处理中&#xff0c;我们经常需要对Excel表格进行操作。Python Pandas库提供了丰富的API来读取、写入、修改Excel表格。本文将介绍如何使用Python Pandas库操作Excel表格&#xff0c;包括向Excel表格添加新行、创建Excel表格等。 1.向Excel表格添加新行 下面是一个…...

LeetCode练习七:动态规划上:线性动态规划

文章目录一、 动态规划基础知识1.1 动态规划简介1.2 动态规划的特征1.2.1 最优子结构性质1.2.2 重叠子问题性质1.2.3 无后效性1.3 动态规划的基本思路1.4 动态规划基础应用1.4.1 斐波那契数1.4.2 爬楼梯1.4.3 不同路径1.5 个人总结二、记忆化搜索2.1 记忆化搜索简介2.2 记忆化搜…...

基于正点原子F407开发版和SPI接口屏移植touchgfx完整教程(一)

一、相关软件包安装 1、打开cubemx包管理器 2、安装F4软件包 3、安装touchgfx软件包 二、工程配置 1、新建工程 2、sys配置 3、rcc配置 4、crc配置 5、添加touchgfx软件包 6、配置touchgfx软件包 将width和height改为自己屏幕尺寸 7、生成工程 三、代码修改 1、将屏幕相关驱…...

Linux--进程间通信

前言 上一篇相关Linux文章已经时隔2月&#xff0c;Linux的学习也相对于来说是更加苦涩&#xff1b;无妨&#xff0c;漫漫其修远兮,吾将上下而求索。 下面该片文章主要是对进程间通信进行介绍&#xff0c;还对管道&#xff0c;消息队列&#xff0c;共享内存&#xff0c;信号量都…...

hadoop伪分布式集群搭建

基于hadoop 3.1.4 一、准备好需要的文件 1、hadoop-3.1.4编译完成的包 链接: https://pan.baidu.com/s/1tKLDTRcwSnAptjhKZiwAKg 提取码: ekvc 2、需要jdk环境 链接: https://pan.baidu.com/s/18JtAWbVcamd2J_oIeSVzKw 提取码: bmny 3、vmware安装包 链接: https://pan.baidu…...

Qt 中的信息输出机制:QDebug、QInfo、QWarning、QCritical 的简单介绍和用法

Qt 中的信息输出机制介绍QDebug在 Qt 中使用 qDebug输出不同类型的信息浮点数&#xff1a;使用 %!f(MISSING) 格式化符号输出浮点数布尔值&#xff1a;使用 %! (MISSING)和 %! (MISSING)格式化符号输出布尔值对象&#xff1a;使用 qPrintable() 函数输出对象的信息qInfoqWarnin…...

C++读写excel文件的的第三方库

一、比较流行的库 1. OpenXLSX 用于读取、写入、创建和修改 Microsoft Excel (.xlsx) 文件的 C 库。 2. xlnt xlnt 是一个现代 C 库&#xff0c;用于操作内存中的电子表格以及从 XLSX 文件读取/写入它们&#xff0c;如ECMA 376 第 4 版中所述。xlnt 1.0 版的首次公开发布是在 …...

【关于Linux中----多线程(一)】

文章目录认识线程创建线程线程优点和缺点创建一批线程终止线程线程的等待问题认识线程 在一个程序里的一个执行路线就叫做线程&#xff08;thread&#xff09;。更准确的定义是&#xff1a;线程是“一个进程内部的控制序列”一切进程至少都有一个执行线程线程在进程内部运行&a…...

2023年全国最新安全员精选真题及答案34

百分百题库提供安全员考试试题、建筑安全员考试预测题、建筑安全员ABC考试真题、安全员证考试题库等&#xff0c;提供在线做题刷题&#xff0c;在线模拟考试&#xff0c;助你考试轻松过关。 11.&#xff08;单选题&#xff09;物料提升机附墙架设置要符合设计要求&#xff0c;但…...

数据出境是什么意思?我国数据出境合规要求是什么?

随着经济全球化深入以及云计算等技术的发展&#xff0c;数据在全球范围跨境流动。数据跨境在促进经济增长、加速创新的同时&#xff0c;对数据主权、数据权属、个人信息保护等一系列问题逐渐浮出水面。今天我们就先来了解一下数据出境是什么意思&#xff1f;我国数据出境合规要…...

Liunx——Git工具使用

目录 1&#xff09;使用 git 命令行安装 git 2&#xff09;在 Gitee 创建仓库 创建仓库 3&#xff09;Linux克隆仓库到本地 4&#xff09;提交代码三板斧&#xff1a; 1.三板斧第一招: git add 2.三板斧第二招: git commit 3.三板斧第三招: git push 5&#xff09;所遇…...

微软语音合成工具+基于Electron + Vue + ElementPlus + Vite 构建并能将文字转换为语音 MP3

微软语音合成工具基于Electron Vue ElementPlus Vite 构建并能将文字转换为语音 MP3 资源下&#xff1a;微软语音合成工具基于ElectronVueElementPlusVite构建并能将文字转换为语音MP3资源-CSDN文库 本文将介绍如何使用微软语音合成工具和前端技术栈进行开发&#xff0c;…...

Mongodb学习笔记2

文章目录前言一、搭建项目二、开始编写java代码1. 新增2.查询3. 修改4. 删除5.根据条件查询6. 关联查询7. 索引相关总结前言 MongoTemplate 相关操作 CRUD,聚合查询等; 一、搭建项目 springboot项目创建引入mongo 依赖docker 安装好mongo数据库配置yml 链接mongo spring:dat…...

学习Tensorflow之基本操作

学习Tensorflow之基本操作Tensorflow基本操作1. 创建张量(1) 创建标量(2) 创建向量(3) 创建矩阵(4) shape属性(5) 判别张量类型(6) 列表和ndarray转张量2. 创建特殊张量(1) tf.ones与tf.ones_like(2) tf.zeros与tf.zeros_like(3) tf.fill(3) tf.random.normal(4) tf.random.uni…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

vue3 字体颜色设置的多种方式

在Vue 3中设置字体颜色可以通过多种方式实现&#xff0c;这取决于你是想在组件内部直接设置&#xff0c;还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法&#xff1a; 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

JVM 内存结构 详解

内存结构 运行时数据区&#xff1a; Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器&#xff1a; ​ 线程私有&#xff0c;程序控制流的指示器&#xff0c;分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 ​ 每个线程都有一个程序计数…...

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要&#xff1a; 近期&#xff0c;在使用较新版本的OpenSSH客户端连接老旧SSH服务器时&#xff0c;会遇到 "no matching key exchange method found"​, "n…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

Golang——9、反射和文件操作

反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一&#xff1a;使用Read()读取文件2.3、方式二&#xff1a;bufio读取文件2.4、方式三&#xff1a;os.ReadFile读取2.5、写…...

tomcat指定使用的jdk版本

说明 有时候需要对tomcat配置指定的jdk版本号&#xff0c;此时&#xff0c;我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...

Xela矩阵三轴触觉传感器的工作原理解析与应用场景

Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知&#xff0c;帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量&#xff0c;能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度&#xff0c;还为机器人、医疗设备和制造业的智…...

LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)

在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...