【3.3.2原生】Bundle释放问题【SOS引擎组速来】

解除业务逻辑层对Bundle的所有引用后,执行assetManager.removeBundle,内存不释放?

那么换一种姿势试试?解除Bundle内资源引用时,对资源进行bundle.release,内存还是不释放?

求解惑,我能保证的是业务逻辑层没有任何Bundle内的资源引用,但是为啥内存不释放呢?

测试场景加内存对比图:


CocosDemo的assets文件夹(已更新至最新0425):
NewProject.zip (2.8 MB)
安卓包因为太大无法上传。

测试脚本(已更新至最新0425):

import { instantiate, Prefab, SpriteFrame, Texture2D } from 'cc';
import { AssetManager } from 'cc';
import { Sprite } from 'cc';
import { _decorator, Component, Node, ParticleSystem, assetManager } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('NewComponent')
export class NewComponent extends Component {

    @property(Sprite)
    private f1: Sprite = null;

    @property(Sprite)
    private f2: Sprite = null;

    @property(Sprite)
    private f3: Sprite = null;

    @property(Node)
    private button1: Node = null;

    @property(Node)
    private button2: Node = null;

    private allPrefab: Prefab[] = [];
    private allNode: { node: Node, url: string }[] = [];
    private isShow_1: boolean = false;
    private isShow_2: boolean = false;
    private bundle1: AssetManager.Bundle = null;
    private bundle2: AssetManager.Bundle = null;

    public onEnable(): void {
        this.f1.spriteFrame = null;
        this.f2.spriteFrame = null;
        this.f3.spriteFrame = null;
        this.bundle1 = null;
        this.isShow_1 = false;
    }

    private click1(): void {
        if (!this.isShow_1) {
            this.isShow_1 = true;
            this.button1.active = false;
            assetManager.loadBundle("testBundle", (error, bundle) => {
                if (error) {
                    console.error(error);
                    return;
                }
                this.bundle1 = bundle;
                let count = 3;
                bundle.load("aigei1/spriteFrame", SpriteFrame, (error, data: SpriteFrame) => {
                    this.f1.spriteFrame = data;
                    // data.addRef();
                    count--;
                    if (count == 0) {
                        this.button1.active = true;
                    }
                });
                bundle.load("aigei2/spriteFrame", SpriteFrame, (error, data: SpriteFrame) => {
                    this.f2.spriteFrame = data;
                    // data.addRef();
                    count--;
                    if (count == 0) {
                        this.button1.active = true;
                    }
                });
                bundle.load("aigei3/spriteFrame", SpriteFrame, (error, data: SpriteFrame) => {
                    this.f3.spriteFrame = data;
                    // data.addRef();
                    count--;
                    if (count == 0) {
                        this.button1.active = true;
                    }
                });
            });
        } else {
            let tempF = this.f1.spriteFrame;
            this.f1.spriteFrame = null;
            // tempF.destroy();
            // tempF.decRef();
            tempF = this.f2.spriteFrame;
            this.f2.spriteFrame = null;
            // tempF.destroy();
            // tempF.decRef();
            tempF = this.f3.spriteFrame;
            this.f3.spriteFrame = null;
            // tempF.destroy();
            // tempF.decRef();
            // this.bundle.releaseAll();
            this.bundle1.release("aigei1/spriteFrame", SpriteFrame);
            // this.bundle.release("aigei1/texture", Texture2D);
            this.bundle1.release("aigei2/spriteFrame", SpriteFrame);
            // this.bundle.release("aigei2/texture", Texture2D);
            this.bundle1.release("aigei3/spriteFrame", SpriteFrame);
            // this.bundle.release("aigei3/texture", Texture2D);
            assetManager.removeBundle(this.bundle1);
            assetManager.releaseUnusedAssets();
            this.bundle1 = null;
            this.isShow_1 = false;
        }
    }

    private click2(): void {
        if (!this.isShow_2) {
            this.isShow_2 = true;
            this.button2.active = false;
            let urlList = [
                "prefab/battleEffect/battleSkillEffect/SK_2020303/SK_2020303_P1_B",
                "prefab/battleEffect/battleSkillEffect/SK_2020303/SK_2020303_P1_C",
                "prefab/battleEffect/battleSkillEffect/SK_2020303/SK_2020303_P1_F",
                "prefab/battleEffect/battleSkillEffect/SK_2020303/SK_2020303_P1_G",
                "prefab/battleEffect/battleSkillEffect/SK_2020303/SK_2020303_P2_B",
                "prefab/battleEffect/battleSkillEffect/SK_2020303/SK_2020303_P2_F",
                "prefab/battleEffect/battleSkillEffect/SK_2020303/SK_2020303_P2_G",
            ];
            assetManager.loadBundle("resBundle", (error, bundle) => {
                if (error) {
                    console.error(error);
                    return;
                }
                this.bundle2 = bundle;
                let count = urlList.length;
                for (const url of urlList) {
                    bundle.load(url, Prefab, (error, data: Prefab) => {
                        if (error) {
                            console.error(error);
                            return;
                        }

                        count--;
                        this.allPrefab.push(data);
                        let node = instantiate(data);
                        node.setParent(this.node);
                        this.allNode.push({ node: node, url: url });
                        if (count == 0) {
                            this.button2.active = true;
                        }
                    });
                }
            });
        } else {
            this.allPrefab = [];
            for (const data of this.allNode) {
                let node = data.node;
                let url = data.url;
                node.removeFromParent();
                node.destroy();
                this.bundle2.release(url, Prefab);
            }
            this.allNode = [];
            assetManager.removeBundle(this.bundle2);
            assetManager.releaseUnusedAssets();
            this.bundle2 = null;
            this.isShow_2 = false;
        }
    }
}

0423续:
刚刚在第三个状态下,又执行了加载Bundle并显示图片,内存竟然比第二个状态多10MB


0425续:
增加了加载、生成和释放粒子预制件逻辑,依旧效果平平。。。

求解惑。

1赞

@muxiandong @jare @panda
3.3.2Bundle释放问题。

@mutu000 @zzf_Cocos 麻烦看看或帮忙反馈一下,解解惑啊,真没辙了

难道这种专业性问题需要开通小秘书才可以被解答吗?

正常修改引用计数就行了,使用时加1,不用减1

释放要加类型 this.bundle.release(“aigei1/spriteFrame”,cc.SpriteFrame);

不好使啊,加类型和releaseAll都试了

也不行,加载前188MB内存,加载后208MB内存,然后就是降不到200以下

@zzf_Cocos @muxiandong 麻烦看看这个帖子,3.3.2原生Bundel释放问题,没辙了啊

试试加上这句cc.assetManager"releaseUnusedAssets";image

好的,我试一下

试了一下,结果贴主题上了,效果一般,还是有没有释放掉的部分。。。

@zzf_Cocos @muxiandong 引擎组大佬麻烦来看看这个帖子吧,3.3.2原生Bundel释放问题,没辙了啊,救救孩子吧。。。

不用看了 js的锅 内存管理是js内部的

还有一个就是openGL 的缓存也不是你释放立刻就能释放了openGL 内部维护了一套机制的

sprite 在 3.4.2 有优化,测试数据是正常,粒子目前是有问题,已经反馈给相关人员了

你好,sprite优化部分的pr能发一下吗?

顶贴 防沉 :6:

改动是在 3.4 的基础上进行的,关联的 pr 有点多,没法发,非常抱歉!