ccc2.1.2 资源释放,错误释放材质依赖问题

  • Creator 版本:2.1.2

  • 目标平台: 所有

  • 详细报错信息,包含调用堆栈:

  • 重现方式:

  • 之前哪个版本是正常的 :1.9.3 2.0.10

  • 手机型号 :

  • 手机浏览器 :

  • 编辑器操作系统 :

  • 编辑器之前是否有其它报错 :

  • 出现概率:必现

  • 额外线索:

cc.loader.getDependsRecursively释放预制体资源的时候会报警告
“res/import/28/2874f8dd-416c-4440-81b7-555975426e93.json” was released but maybe still referenced by “res/import/6f/6f801092-0c37-4f30-89ef-c8d960825b36.json” (6fgBCSDDdPMInvyNlggls2)

原来在2.0.10,1.9.3 正常的资源释放逻辑,在2.1.2会出问题。

大概原因如下,现在的Sprite都改用了材质。

加载Sprite A,将其依赖引用+1 值为1
SpriteA Destroy, 将期依赖引用-1 值为0

此时对引用为0的依赖 调用 cc.loader.release

此时会警告 例似这样的语句:“res/import/02/0275e94c-56a7-410f-bd1a-fc7483f7d14a.json” was released but maybe still referenced by “res/import/2a/2a296057-247c-4a1c-bbeb-0548b6c98650.json” (2a296057-247c-4a1c-bbeb-0548b6c98650)

去Library查看,发现这个会释放的依赖是 内置材置 的依赖。 内置材质应该是引擎自动加载,存在于内存当中,而开发者的内存管理逻辑没有主动为 引擎自动加载的资源 引用加1.所以造成这个问题。

解决办法:
1.引擎提供 一个接口,开发者可以获取 引擎自动加载资源的所有依赖 开发者内存管理逻辑主动为这些依赖引用+1
2.引擎提供一个接口,开发者去记录依赖时,判断此依赖存在于引擎自动加载的资源当中。 如果是,则不处理
3.引擎 cc.loader.release 自行实现,不对引擎内置资源做处理

临时解决方案:
查看引擎置内置资源目录:

这些材质资源应该是被引擎 自动加载到 内存里面了

那么针对此这些材质依赖引用+1即可,这样此精灵在我们的内存管理逻辑里面,永远不会被释放,不会出现上述问题


ResUtil.loader.lockAsset是我自已逻辑的实现,对资源的依赖进行引用+1 操作。

但这只是临时解决方案,尚不知引擎自动加载了哪些资源在内存中,仍有风险。

希望引擎大大早日解决,解决PR也麻烦发到这里。

@jare

升级上来,确实有这个问题,
研究了一下,(不知道你的this.materialList是如何获取的),
可以使用下面的方式获取

    let materials = cc.AssetLibrary.getBuiltins("material");
    for (const material in materials) {
        //todo 
    }

修复将会进入 2.1.3,代码 https://github.com/cocos-creator/engine/pull/4915