极简资源释放

使用的引擎:Cocos Creator v2.2.0
移植自Cocos Creator 3D v1.2.0。
详细使用看这里:分享一个极简的资源释放解决方案
v2.2.0 demo样例:ResCleaner-cocos-v220.rar (403.1 KB)

有效帮助降低内存占用。

7赞

你在原生平台上有测过, 释放之后内存下降了吗?

我目前释放之后, loader._cache 内已经没有引用了。 但是内存还没有释放掉。

我是在浏览器里面测试的。js gc有一定的延迟。

原理是什么? 只是释放引用?,

遍历整个场景上所有节点,统计节点上组件对资源的引用。

释放逻辑如下:

  1. 遍历场景上所有节点,搜集每个节点上所有组件引用的资源。
  2. 收集所有正在加载中的资源(loader.loadRes、loader.loadResArray)
  3. 遍历资源缓存(loader._cache)。如果当前资源既没有被场景节点引用又不属于加载中则释放。

有点类似js本身的垃圾回收。只要场景上有节点引用了这个资源,它就不会被回收掉。

忘记放2.2的demo了 :v2.2 demo

已经在真机上测试过,是有效的。代码略有改动

收藏一波~

从2.4.3开始不是官方有addDef,decRef了吗,直接基于这个做一个component挂载到界面或者场景上不是更简单吗

1赞

我现在的项目已经用这个上线了。只需要调用一下函数,并不需要对项目做任何的改动。你说的每个界面挂脚本也很麻烦的样子啊。

用这个会把预加载的资源以及组件通过property方式引用的资源释放掉,楼主是怎么处理的呢?

组件的property引用的资源不会被释放掉。
预加载的资源需要增加一个白名单机制

Cocos v2.2.2 demo
fix 自动合图未处理的bug
fix 手动创建的spriteFrame未处理的bug
增加白名单机制
ResCleaner-cocos-v222.zip (446.5 KB)

1赞

老哥升到2.4了吗,最近我在升2.4,感觉坑有点多

试试这个呢?ResourceManager基于引用计数的资源管理

1赞

我准备直接升级到3.0版本了

private _decRef(asset: cc.Asset, delta: number = 1) {
    if (this.autoRelease && asset) {
        if (asset instanceof cc.MaterialVariant) {
            //@ts-expect-error
            asset = asset.material
        }
        let dynamicAsset = asset as DynamicAsset
        if (dynamicAsset._dynamic != DynamicState.STATIC && dynamicAsset._dynamic != DynamicState.UNUSE) {
            dynamicAsset._dynamic -= delta
            dynamicAsset._ref -= delta
            //引用计数不为0 可能是循环引用也需要做释放检测
            this.tryRelease(dynamicAsset._uuid)
        }
    }
}

计数只要减了,都try释放吗?

2.3以上本来底层就是引用计数,只需要自己去管理资源的使用就好,楼主的方案也只适合2.3及以下,通过楼主的这个方案和2.4自带的资源管理接口集合,就可以做一个体积小,兼容性强的资源管理器,我目前就是这么做的

1赞

markkkkkkk