小白问题…
我知道resources.load如果没有调用addRef,资源使用完后会自动释放。可是preload是没有使用资源就已经缓存了,那引擎会在load之后使用完资源后自动释放资源吗?
或者有时候preload的资源,在之后又判定不需要使用了的情况,又该如何处理?
preload 只下载资源的配置,还没到资源解析呢,所以不需要去处理资源引用。
那如果preload之后不load加载的资源,会怎么样?这个资源就一直在缓存里?
就是静静的占用你的硬盘而已 没有其他影响
比如使用 resources.preload 预加载本地的文件,然后不调用resources.load,本地文件的大小会增加?
其实官方真应该把preload 改成download,这样就没有迷惑性了
我擦,所以本地文件根本不需要preload吗…
严格来说,preload也占用内存,而且还不小。
如果看到cocos源码的话,会发现shared.ts 里面有2个cache,files和parsed。在preload的时候,走的fetch 的pipeline,会把下载结果和解析结果加入这2个cache,保存住让内存上涨,但是没有删除(或者删除不彻底)。你们在预加载的时候,打印这2个cache的count就看到了。
对,preload也会去做解析,是获取资源依赖(getDepends)的时候进行parsed。如果不解析,怎么能从json里面获取依赖的资源引用呢?
这2个cache的删除是在load的时候删除的(也会删除不彻底),我是用各种修改才让这2个cache清理的稍微干净一点。
卧槽…那新手是不是该尽量不用preload了…
其实关系不大,用就是了,我是提示一下可能存在的bug。
我们都是用preload的,只是preload比较大量的时候,可能内存会上涨。至少比直接load好太多了。
顺带贴一下我一部分修改的图,这个可以解决预加载中parsed的cache堆积的问题。目前用着还行但没充分测试。
parsed堆积的还挺大的,特别是一些骨骼动画的数据。
在fetch的时候,由于调用了getDepends而加载的依赖,没有走load的流程卸载掉。导致的问题。
看了下源码,对你这部分修改有个疑问。
如果在fetch这里清理了files,那后续在真正要load某个已经preload了的资源的话,会在packmanager的load阶段去检查files是否存在,如果不存在会走downloader.download,此次如果被下载并发上限限制住的话,这个预加载效果会打折扣(也就是要等待并发低于限制才会从浏览器缓存中查询命中)
不知道是不是我理解错了,还是说你做了什么别的逻辑修改去规避掉这个问题?
我看了一下,我没对downloader的上层做处理,所以确实会有被并发限制住的问题。
不过如果你要解决这个问题也很方便,downloader里面额外增加一个判断url是否已经下载到本地的函数,然后让每个平台去覆盖。
举个例子,我们可以加downloader.isPreloaded,针对小游戏平台,我们可以这样处理:
FILE: platforms\minigame\common\engine\AssetManager.js
function isPreloaded(url,options) {
const result = transformUrl(url, options);
return result.inLocal;
}
downloader.isPreloaded = isPreloaded
这样在小游戏平台,我们就可以不需要files的map就可以判断是否已经下载到本地了。在downloader.download 接口里面先调用这个就可以快速返回了。
其他的平台各自判断,例如原生IsFileExist等。如果有平台判断不了那就还是受到并行的限制。
其实,原理就是把查询命中提前,查询命中很快而且也不会影响内存堆积。
不对吧,只要动态加载的资源,你手动load后是一直不会自动释放的。你说的“使用完后”是什么意思
