Unity加载和内存管理机制

Unity内存管理 Unity Native Memory管理:重载了所有分配的操作符(new),使用重载过的操作符时需要一个额外的参数memory lable(当前这块内存需要分配到那个类型池中),Unity在底层会使用Allocator会根据memory lable来分配到Allocator池中,需要访问时就直接去Allocator池中询问有多少东西大小多大。物理内存:CPU访问内存是一个慢速过程,我们需要做的是减少Cache miss,就让内存从数据不连续的状况变为内存连续的情况,所以Unity提供了ECS和DOTS。 阅读详情
Unity几种动态加载Prefab方式的差异:
其实存在3种加载prefab的方式:

一是静态引用,建一个public的变量,在Inspector里把prefab拉上去,用的时候instantiate
二是Resource.Load,Load以后instantiate
三是AssetBundle.Load,Load以后instantiate
三种方式有细节差异,前两种方式,引用对象texture是在instantiate时加载,而assetBundle.Load会把perfab的全部assets都加载,instantiate时只是生成Clone。所以前两种方式,除非你提前加载相关引用对象,否则第一次instantiate时会包含加载引用类assets的操作,导致第一次加载的lag。官方论坛有人说Resources.Load和静态引用是会把所有资源都预先加载的,反复测试的结果,静态引用和Resources.Load也是OnDemand的,用到时才会加载。



几种AssetBundle创建方式的差异:
CreateFromFile:这种方式不会把整个硬盘AssetBundle文件都加载到内存来,而是类似建立一个文件操作句柄和缓冲区,需要时才实时Load,所以这种加载方式是最节省资源的,基本上AssetBundle本身不占什么内存,只需要Asset对象的内存。可惜只能在PC/Mac Standalone程序中使用。
CreateFromMemory和WWW.assetBundle:这两种方式AssetBundle文件会整个镜像于内存中,理论上文件多大就需要多大的内存,之后Load时还要占用额外内存去生成Asset对象。


什么时候才是UnusedAssets?
看一个例子:
Object obj = Resources.Load("MyPrefab");
GameObject instance = Instantiate(obj) as GameObject;
.........
Destroy(instance);
创建随后销毁了一个Prefab实例,这时候 MyPrefab已经没有被实际的物体引用了,但如果这时:
Resources.UnloadUnusedAssets();
内存并没有被释放,原因:MyPrefab还被这个变量obj所引用
这时候:
obj  = null;
Resources.UnloadUnusedAssets();
这样才能真正释放Assets对象
所以:UnusedAssets不但要没有被实际物体引用,也要没有被生命周期内的变量所引用,才可以理解为 Unused(引用计数为0)

所以所以:如果你用个全局变量保存你Load的Assets,又没有显式的设为null,那在这个变量失效前你无论如何UnloadUnusedAssets也释放不了那些Assets的。如果你这些Assets又不是从磁盘加载的,那除了UnloadUnusedAssets或者加载新场景以外没有其他方式可以卸载之。


一个复杂的例子,代码很丑陋实际也不可能这样做,只是为了加深理解

IEnumerator OnClick()
{
    Resources.UnloadUnusedAssets();//清干净以免影响测试效果
    yield return new WaitForSeconds(3);
    float wait = 0.5f;
    //用www读取一个assetBundle,里面是一个Unity基本球体和带一张大贴图的材质,是一个Prefab
    WWW aa = new WWW(@"file://SpherePrefab.unity3d");
    yield return aa;
    AssetBundle asset = aa.assetBundle;
    yield return new WaitForSeconds(wait);//每步都等待0.5s以便于分析结果
    Texture tt = asset.Load("BallTexture") as  Texture;//加载贴图
    yield return new WaitForSeconds(wait);
    GameObject ba = asset.Load("SpherePrefab") as  GameObject;//加载Prefab
    yield return new WaitForSeconds(wait);
    GameObject obj1 = Instantiate(ba) as GameObject;//生成实例
    yield return new WaitForSeconds(wait);
    Destroy(obj1);//销毁实例
    yield return new WaitForSeconds(wait);
    asset.Unload(false);//卸载Assetbundle
    yield return new WaitForSeconds(wait);
    Resources.UnloadUnusedAssets();//卸载无用资源
    yield return new WaitForSeconds(wait);
    ba = null;//将prefab引用置为空以后卸无用载资源
   Resources.UnloadUnusedAssets();
   yield return new WaitForSeconds(wait);
   tt = null;//将texture引用置为空以后卸载无用资源
   Resources.UnloadUnusedAssets();
}
 


说明:
1        初始状态
2        载入AssetBundle文件后,内存多了文件镜像,用量上升,Total Object和Assets增加1(AssetBundle也是object)
3        载入Texture后,内存继续上升,因为多了Texture Asset,Total Objects和Assets增加1
4        载入Prefab后,内存无明显变化,因为最占内存的Texture已经加载,Materials上升是因为多了Prefab的材质,Total Objects和Assets增加6,因为 Perfab 包含很多 Components
5        实例化Prefab以后,显存的Texture Memory、GameObjectTotal、Objects in Scene上升,都是因为实例化了一个可视的对象
6        销毁实例后,上一步的变化还原,很好理解
7        卸载AssetBundle文件后,AssetBundle文件镜像占用的内存被释放,相应的Assets和Total Objects Count也减1
8        直接Resources.UnloadUnusedAssets,没有任何变化,因为所有Assets引用并没有清空
9        把Prefab引用变量设为null以后,整个Prefab除了Texture外都没有任何引用了,所以被UnloadUnusedAssets销毁,Assets和Total Objects Count减6
10        再把Texture的引用变量设为null,之后也被UnloadUnusedAssets销毁,内存被释放,assets和Total Objects Count减1,基本还原到初始状态

从中也可以看出:
Texture加载以后是到内存,显示的时候才进入显存的Texture Memory。
所有的东西基础都是Object
Load的是Asset,Instantiate的是GameObject和Object in Scene
Load的Asset要Unload,new的或者Instantiate的object可以Destroy

Unity加载和内存管理全面理解 Unity加载和内存管理全面理解 Unity 3D 里有两种动态加载机制: 一是 Resources.Load; 一是通过 AssetBundle; 立即下载

相关推荐

麦当劳app之sign逆向分析

摘要:本文分析了麦当劳APP请求参数sign的逆向过程。通过抓包发现32位sign参数疑似MD5加密,使用frida-trace工具跟踪CC_MD5函数验证其为标准MD5算法。加密参数包含时间戳、token、版本号等固定和动态字段,拼接后经MD5加密生成sign。文章提供了JS和Python两种实现方案,包含完整的请求头参数和加密逻辑,最终成功获取API响应数据。该研究仅用于逆向技术学习,展示了移动应用常见加密参数的逆向分析方法。

佛系更新... 2436

【不用找素材】ECS 游戏Demo制作教程(3) 1.17

赋个值这边也能看到了再写个新脚本。

m0_53930254的博客 859

《揭秘 BME688人工智能压力湿度温度气体传感器:气体检测的多面能手》:此文为AI自动生成

BME688 是博世推出的一款具有人工智能和集成高线性度高精度压力、湿度、温度传感器的气体传感器,专为移动和联网应用开发,尺寸紧凑且低功耗。BME688 作为一款先进的传感器,在多个领域展现出卓越的性能。它采用了坚固而紧凑的 3.0 x 3.0 x 0.9 mm³ 封装,这种小巧的尺寸使其能够轻松应用于对空间要求严格的移动设备和联网应用中。同时,低功耗的特性也使得它在能源有限的环境下能够长时间稳定运行。

zheng_ruiguo的专栏 1927

Unity动态加载和内存管理(三合一)。。。好强悍。。。

原址:http://game.ceeger.com/forum/read.php?tid=4394#info 最近一直在和这些内容纠缠,把心得和大家共享一下: Unity里有两种动态加载机制:一是Resources.Load,一是通过AssetBundle,其实两者本质上我理解没有什么区别。Resources.Load就是从一个缺省打进程序包里的AssetBundl

㊰ ❀ ☀ ☁ ☂ ☃ 1万+

欧姆龙PLC EIP通讯配置方法

欧姆龙EIP通讯配置方法

weixin_59671695的博客 6135

【迁移学习综述】

迁移学习的目标是将某个领域或任务上学习到的知识应用到不同的但相关的领域或问题中。迁移学习的研究来源于一个观测:人类可以将以前的学到的知识应用于解决新的问题,更快的解决问题或取得更好的效果。迁移学习被赋予这样一个任务:从以前的任务当中去学习知识(knowledge)或经验,并应用于新的任务当中。换句话说,迁移学习目的是从一个或多个源任务(source tasks)中抽取知识、经验,然后应用于一个目标领域(target domain)当中去。

afadgas的博客 4319

unity加载场景和切换场景

因为公司没什么大牛,所以很多东西只能自己摸索。 好像网上加载场景和切换场景有2种主流的方式 1)用Scenemanager加载和切换scene 2)将scene做成prefab,加载和切换prefab 我用的是第二种方式 1)将preafab打包成assetbundle 代码如下 : // Builds an asset bundle from the selected objec...

write_the_code的博客 6970

1、2022 应用密码学与网络安全会议亮点与关键技术解读

2022年应用密码学与网络安全会议(ACNS 2022)在意大利罗马成功举办,会议涵盖了密码学与网络安全的多个前沿领域,包括键控全同态加密、隐私保护技术、区块链、后量子密码学和多方计算等。会议共收录44篇论文,展示了众多创新的研究成果,为学术研究和实际应用提供了新的思路和方法。本次会议促进了学术界和工业界的交流与合作,推动了密码学与网络安全行业的发展。

blue的专栏 182

Unity内存管理的原理

【前言】 当我们谈及Unity内存管理时,我们更多的是在说手游项目上如何更好的去管理内存,如果是在端游项目上,没有那么多讲究,内存随便用。 【为什么手机上内存不够用】 CPU读写速度远快于内存的速度,大多数时候CPU都在等内存给数据,为了缓解主存速度慢、跟不上CPU读写速度要求的矛盾,进而提高程序运行效率,CPU设计时引入了高速缓冲存储器。在PC中,CPU一般有三级缓存,大小共8~16M。而手机没有独立显卡、独立显存,CPU和GPU共用一个缓存,其内存更小,缓存级数更少、大小仅为2M。 PC有内存.

enternalstar的博客 2917

2020年信奥赛C++提高组csp-s初赛真题及答案解析(阅读程序第3题)

2020年信奥赛C++提高组csp-s初赛真题及答案解析(阅读程序第3题)

王老师青少年编程 989

X86/64架构中的总线 和 ARM架构中总线的理解

内部总线 /CPU总线/FSB前端总线:类似ARM架构中的AHB总线北桥? 直接和CPU连接,这条总线主要由CPU使用,用来与高速缓存、主存和北桥(或MCH)之间传送信息。 外部总线:类似ARM架构中的APB总线(外围总线)南桥?例如PCI总线、USB总线等 通过北桥与CPU连接(南桥?),是CPU与内存RAM、ROM和输入/输出设备接口之间进行通讯的通路 内存总线:内存与北桥间的总线称为内存总线 ...

a746742897的博客 1066

[转]全面理解Unity加载和内存管理机制之一

作者: hog Unity里有两种动态加载机制:一是Resources.Load,一是通过AssetBundle,其实两者本质上我理解没有什么区别。Resources.Load就是从一个缺省打进程序包里的AssetBundle里加载资源,而一般AssetBundle文件需要你自己创建,运行时动态加载,可以指定路径和来源的。其实场景里所有静态的对象也有这么一个加载过程,只是Unity后台替

costfine的专栏 544

基于Java+SpringBoot+微信小程序实现奶茶点单系统

再不用担心逢年过节的第一杯奶茶有没有人送了,制作一个奶茶点单系统自己当店主,开怀畅饮,一劳永逸。

商务合作 / 项目定制 / 学习交流。个人vx:lovely_wml 1万+

Unity加载和内存管理机制(一)

最近一直在和这些内容纠缠,把心得和大家共享一下: Unity里有两种动态加载机制:一是Resources.Load,一是通过AssetBundle,其实两者本质上我理解没有什么区别。Resources.Load就是从一个缺省打进程序包里的AssetBundle里加载资源,而一般AssetBundle文件需要你自己创建,运行时动态加载,可以指定路径和来源的。 其实场景里所有静态的对象也有

vo_3180的博客 432

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

全面理解Unity加载和内存管理机制之二:进一步深入和细节

http://game.ceeger.com/forum/read.php?tid=4466 Unity几种动态加载Prefab方式的差异: 其实存在3种加载prefab的方式: 一是静态引用,建一个public的变量,在Inspector里把prefab拉上去,用的时候instantiate 二是Resource.Load,Load以后instantiate 三是AssetBund

afteryunlei的专栏 608

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

[转]全面理解Unity加载和内存管理机制之二:进一步深入和细节

作者: hog Unity几种动态加载Prefab方式的差异:其实存在3种加载prefab的方式:一是静态引用,建一个public的变量,在Inspector里把prefab拉上去,用的时候instantiate二是Resource.Load,Load以后instantiate三是AssetBundle.Load,Load以后instantiate三种方式有细节差异,前两种方式,引用对象te

costfine的专栏 687

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Unity加载和内存管理机制(二)

全部在一个帖子里内容太多了,这里另起一个继续探讨   Unity几种动态加载Prefab方式的差异: 其实存在3种加载prefab的方式: 一是静态引用,建一个public的变量,在Inspector里把prefab拉上去,用的时候instantiate 二是Resource.Load,Load以后instantiate 三是AssetBundle.Load,Load以后instant

vo_3180的博客 386
上一篇: cocos2d-x 入门 环境安装
下一篇: unity Get与Post的方式获得数据
cheneystudy
博客等级 码龄16年 49粉丝 37原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值