HappyKocola 2019-06-20
最近给项目改造AssetBundle系统,又重新摸起了AssetBundle这块儿。。
因为现在使用4.x版本的情况已经越来越少,而在5里面unity3d已经原生支持了依赖分析增量构建等重量级功能,所以我就不再浪费篇幅去讲系统设计相关的话题。
我花了一些时间做了一些小实验,可以明确一些unity3d在AssetBundle上的处理细节。希望看到这篇文章的人能够从中获取一些营养。
问:当使用WWW加载AssetBundle时,WWW.Dispose()和AssetBundle.Unload(false)两个释放操作分别会如何影响内存?
答:单独调用WWW.Dispose会释放掉一部分内存(并不知道是什么内存,猜测是和网络相关的部分);单独调用AssetBundle.Unload不会带来任何内存变化;同时调用这两个接口可以完全释放内存。
实验过程:
打包9个AssetBundle,每个Bundle中有一张2048x2048的RGBA32格式纹理(16MB)。
使用Profiler和任务管理器观察内存变化。
问:重复从同一个AssetBundle中加载资源,会带来怎样的内存变化?
答:只会在CPU端占用一份内存,但在GPU部分,每次加载都会额外占用一份内存。
实验过程:
打包一张2048x2048的RGBA32格式纹理(16MB)为AssetBundle。
反复进行"加载,取得ResourceObject,卸载Bundle"的操作,使用Profiler观察内存变化。
其中,来自Unity的16MB增长是什么呢?从Profiler Detailed里可以看到具体项目。
一个叫做GfxClientDevice的项目从8.0MB提升到了24.0MB。
至于这个GfxClientDevice项目到底是什么呢? 我日后再调查补充。。。。
问:如果我打包Bundle和运行并不在一个AssetBundle中,可以正确的加载资源吗?
答:可以。
问:如果我把Shader随着Bundle一起打包出来,而运行的工程并没有这个Shader,那么Shader可以正常运作吗?
答:可以。
问:如果两个Bundle都包含同样的资源(未处理共享依赖),加载Bundle的时候unity3d如何处理引用?
答:会各自加载自己包里的资源。
问:在两次不相干的打包过程中,依赖是否可以有效的保持。
答:如果使用Deterministic参数,则可以保持。反之则不能,需要重新打包所有相关Bundle。
实验过程: 有资源A,B,C,其中资源B和资源C都依赖于A。每个资源打一个Bundle。
不开启Deterministic。先带依赖打包A和B,不包含C。然后重新带依赖打包A和C,不包含B。在运行时B会丢失对A的引用。
开启Deterministic。同上流程,在运行时B依然可以保持对A的引用。