统一的缓存管理
接上一篇 资源管理,Addressable Assets,统一的缓存管理是我们跟 Addressable 的主要区别,先上总体图

Cache 是资源对象缓存,减少资源重复加载开销
function Cache:setCachePolicy(maxsize, timeout_seconds)
此 cache 最多缓存额外 maxsize 个资源,这些额外的资源在 timeout_seconds 秒后也被释放。 参考 Cache.lua
注意这里不是只有一个全局的 Cache,而是分类了。每个 assetpath 唯一对应一个 cache, 这种对应关系被记录在我们的 assetinfo 和 cachepolicy 表中,这两个表是我们打 assetbundle 时生成的。
具体实际的缓存策略如下:
--- 战斗音效,ui音效,音乐
setpolicy(assetcachepolicy.fightsound, 100, 50)
setpolicy(assetcachepolicy.uisound, 3, 15)
setpolicy(assetcachepolicy.sound, 0)
--- ui
setpolicy(assetcachepolicy.ui, 0)
--- altas 之前是32,15导致在panelfashion界面来回持续切换tab页时,SetSprite就会重新加载sprite,unity c++就持续分配内存,GetTotalAllocatedMemoryLong持续提高
--- 这里cache设置高一点,避免持续分配
setpolicy(assetcachepolicy.atlas, 180, 30)
setpolicy(assetcachepolicy.emoticonanimator, 16, 15)
--- 这个是人物头像图片,角色有100个好友,所以这里设置100
setpolicy(assetcachepolicy.netsprite, 100, 15, {100, 15})
--- anim, shader
setpolicy(assetcachepolicy.anim, 8, 10)
setpolicy(assetcachepolicy.shader, 4, 15)
--- prefab
setpolicy(assetcachepolicy.avatar, 0)
setpolicy(assetcachepolicy.sfx, 0)
Pool 是场景对象缓存,减少 prefab 实例化开销
function Pool:setCachePolicy(max_extra_go_size, max_extra_res_size, timeout_seconds)
此pool最多额外缓存 max_extra_go_size 个 GameObject, 这个额外缓存的 GameObject 最多额外占用 max_extra_res_size 个资源, 这些额外缓存在 timeout_seconds 后被释放。参考 Pool.lua
同样这里也不是一个全局性的 Pool,而是分类。要得到GameObject必须提供pool, 使用接口在 loader.lua 里:
local loader = makeGameObj(pool, assetinfo)
具体的缓存策略如下:
mkpool("character", 20, 5, 15)
mkpool("attachment", 100, 32, 20)
mkpool("sfx", 20, 10, 10)
--- 自己的技能特效,就高低内存都多多缓存,并且不随时间释放
mkpool("myhero_sfx", 50, 35, nil, { 50, 35 })
mkpool("otherhero_sfx", 380, 300, 30)
mkpool("other_sfx", 20, 10, 15)
mkpool("sceneobj", 10, 5, 10)
local panelpool = Pool:new("panel", nil, 0, 0)
local worldpanelpool = Pool:new("worldpanel", nil, 0, 0)
resmgr.setCachePolicyParam(uimgr.component_singltonpool, { 1, 20 }, { 1, 3 })
resmgr.setCachePolicyParam(uimgr.component_multipool, { 40 }, { 20 })
有些细节:
-
pool 下面还有 cache 做缓存,双层缓存,但 prefab 的 cache 都是 0,都在 pool 里去配置缓存,因为:在最靠近 user 的地方配缓存。
-
看到 ui 的 pool 缓存都是 0,因为上层还有一层 lua 对象的缓存,这个 lua 对象包含 GameObject, 单例的 UI 界面只缓存一个,而多例的 worldpanel 缓存 40 个。
统一的缓存策略
好处:
-
其他逻辑程序不用考虑缓存策略,而是在一个集中的地方被做优化的程序统一管理。
-
可以附加进一步的自适应策略,比如 OS 发出低内存警告后,所有的缓存策略 max_size 都除以 2,甚至把额外缓存全部清掉。
下一篇讲自动化的打包策略