Unity性能调优手册5:Assetbundle颗粒,加载API,卸载策略,同时加载数量

翻译自https://github.com/CyberAgentGameEntertainment/UnityPerformanceTuningBible/
AssetBundle配置中的问题可能会导致许多问题,例如浪费用户宝贵的通信和存储空间,以及阻碍舒适的游戏体验
在这里插入图片描述

AssetBundle的粒度

由于依赖问题,应该仔细考虑AssetBundle的粒度。在极端情况下,有两种方法可以做到这一点:将所有资源放在一个AssetBundle中,或者将每个资源放在一个AssetBundle中。两种方法都很简单,但前一种方法有一个关键问题。前一种方法很简单,但前一种方法有一个致命的问题:即使您只添加或更新一个资产,您也必须重新创建整个文件并分发它。如果资产总量以GB为单位,则更新负载非常高。
因此,选择尽可能多地划分AssetBundle的方法,但如果过于详细,就会在各个方面造成开销。因此,我们基本上建议使用以下策略来制作AssetBundle。
•应该同时使用的资源应该合并到一个单一的AssetBundle中。
•被多个资源引用的资源应该放在单独的assetbundle中。
这很难完美地控制,但在项目中设置一些关于粒度的规则是一个好主意

加载AssetBundle的API

从AssetBundle中加载资源有三种类型的api。
AssetBundle.LoadFromFile
通过指定存储中存在的文件路径加载。通常使用这种方法,因为它是最快和最节省内存的方法。
AssetBundle.LoadFromMemory
通过指定已经加载到内存中的AssetBundle数据来加载。在使用AssetBundle时,需要在内存中维护非常大量的数据,并且内存负载非常大。由于这个原因,它通常不被使用AssetBundle.LoadFromStream
通过指定返回AssetBundle数据的Stream来加载。当在解密时加载加密的AssetBundle时,使用此API时要考虑到内存负载。然而,由于Stream必须是可搜索的,所以要小心不要使用不能处理seek的密码算法。
总结:
使用AssetBundle.LoadFromFile,并使用异步方式

AssetBundle卸载策略

如果AssetBundle在不再需要的时候没有被卸载,它会占用内存。AssetBundle.Unload(bool unloadAllLoadedObjects)是本例中要使用的API,它非常重要,应该在开发开始时决定如何设置它。如果这个参数为真,当卸载一个AssetBundle时,从该AssetBundle加载的所有资源也将被卸载。如果为false,则不卸载任何资产。
换句话说,真正的情况,即要求在使用资产时持续加载AssetBundle,更占用内存,但也更安全,因为它确保了资产被销毁。另一方面,false情况的内存负载很低,因为当资源加载完成时,AssetBundle可以被卸载。但是,忘记卸载已使用的资产可能导致内存泄漏或导致在内存中多次加载相同的资产,因此需要适当的内存管理。因此,需要适当的内存管理。一般来说,严格的内存管理是很严重的,所以AssetBundle。如果内存负载足够,建议使用Unlo ad(true)。
译者增加部分
概述
1.需要内存管理,AssetBundle跟对象池结合
2.务必使用Unload(true),避免内存碎片
参考GF中资源管理
【腾讯文档】GF实体,对象池,资源管理,自动释放
https://docs.qq.com/doc/DWklIdGFNWlhtWE1K

优化同时加载Assetbundle的数量

在AssetBundle. unload (true)的情况下,当资源正在使用时,AssetBundle不能被卸载。因此,根据AssetBundle的粒度,可能会出现同时加载100多个AssetBundle的情况。在这种情况下,您需要注意文件描述符限制和PersistentManager.Remapper的内存使用情况。
文件描述符是操作系统在读写文件时分配的操作ID。读写一个文件需要一个文件描述符,当文件操作完成时文件描述符被释放。由于一个进程可以拥有的文件描述符的数量是有限的,因此不可能同时打开超过这个数量的文件。如果您看到错误消息“打开的文件太多”,这意味着进程已达到限制。因此,在AssetBundle中同时加载的数量受到这个限制的影响,Unity也必须为这个限制保留一定的余量,因为它必须打开一些文件。该限制因操作系统和版本而异,因此有必要提前调查目标平台的值。即使达到了限制,也可以根据操作系统临时提高限制,因此如果有必要,请考虑实现这一点。
同时加载多个assetbundle的第二个问题是PersistentManager的存在。Unity中的Remapper。简单地说,PersistentManager是一个在Unity中管理对象和数据之间映射关系的函数。换句话说,你可以想象它使用的内存与同时加载的AssetBundle的数量成比例,但问题是,即使你释放了一个AssetBundle,所使用的内存空间也没有释放,而是池化了。由于这种特性,内存的压缩将与并发负载的数量成比例,因此减少并发负载的数量非常重要。
基于以上,当在AssetBundle.Unload(true)策略下操作时,建议最大并发加载assetbundle的数量为150到200,当在AssetBundle.Unload(false)策略下操作时,建议最大数量为150或更少。
译者增加部分
GF中有任务池概念执行Assetbundle加载,每次取空闲任务代理执行加载,加载完成后释放任务代理到空闲次,等下个任务加载
【腾讯文档】GF实体创建加载任务
https://docs.qq.com/flowchart/DWmRRdlZ4TFBmblNr

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值