Unity内存存储揭秘

原创 2017年07月06日 20:57:21

笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,已出版书籍:《手把手教你架构3D游戏引擎》电子工业出版社和《Unity3D实战核心技术详解》电子工业出版社等。

CSDN视频网址:http://edu.csdn.net/lecturer/144

内存优化是一个老生常谈问题了,本篇博客把一些关于内存的知识点做了一个总结,给读者介绍一下,我们查看游戏运行内存问题,通常的做的法是借助一些Unity的第三方工具,但是作为程序来说还是先要明白其导致内存的问题所在,才能对症下药,先看通过Profiler显示的内存:

Used Total和Reserved 均是物理内存,其中Reserved是unity向系统申请的总内存,Unity底层为了不经常向系统申请开辟内存,开启了较大一块内存作为缓存,即所谓的Reserved内存,而运行时,unity所使用的内存首先是向Reserved中来申请内存,当不使用时也是先向Reserved中释放内存,从而来保证游戏运行的流畅性。
一般来说,我们均建议尽可能地控制Used Total的大小,Used Total越大,则Reserved Total越大,而当Used Total降下去后,Reserved Total也是会随之下降的(但并不一定与Used Total同步)。

通过PSS来查看移动端的内存是相当不准确的。Profiler记录的是通过引擎分配的真实物理内存,而PSS中多出的内存大致分为两部分,一部分是App在运行会调用底层的一些核心库,这些库都会占用一定的内存;第二部分则是移动系统决定的,即虽然游戏中已经将资源卸载掉,但在系统层面上,系统并不会及时将其清除,而是将其缓存住,这样做的处理是为了便于以后该资源的复用效率,同时,当系统的内存分配达到上限时,系统本身会调用内存清理机制来轮询这些缓存区域,进而释放内存。

ManagedHeap的内存值是由所写的C#代码来引起并造成的,建议时刻关注CPU Profiler中的GC Collcet值,查看由哪些选项分配较大或不断分配GC Allocation。这个是造成ManagedHeap不断增大的原因。

GfxDriver可以理解为GPU显存开销,主要由Texture,Vertex buffer以及index buffer组成。所以尽可能地减少或释放Texture和mesh等资源,即可降低GfxDriver内存。

ManagedHeap的大小与你的GameObject数量、资源量无关,仅是你的代码造成的。如果是在Editor中运行时,那么该数值是会比较大,因为编

辑器运行游戏时,底层会做很多额外的事情,比如更多的log输出等,从而占据较多的堆内存。而如果在真机运行时看到该数值时,那么80M是比较大

的,这个需要你对你的代码来进行优化,避免一些不必要的堆内存分配。比如,不要总是new一个class、array、container等等。你可以在CPU Profiler

中的GC Alloc处查看游戏每帧的堆内存分配。同时,Managedheap的大小完全是有Mono来决定的,用户所写的任何脚本均是由Mono来负责解析。

同时,Mono的堆内存是只升不降的,这是Mono的一个问题,Unity暂时也无法对其进行修改。因此,只能建议开发者在编写代码时尽可能地优化嗲吗,

避免不要的堆内存分配。

另外,Mono内存和native内存是PSS内存主要的组成部分,mono内存更多的起到内存调用的功能,因此常常成为了开发人员优化内存的起点;

而native内存中包含了大量对象的资源,也是内存优化中的重要部分。

再以NGUI或者说UGUI为例如何去做优化:

通常一个Panel会产生1个或多个Draw Call,以一个Panel为单位,Draw Call 的数量通常由当前 Panel 中
使用的Atlas、Font的数量所决定。


要降低UI渲染时的 Draw Call数量则需要对 Atlas 的制作进行合理的规划,即在保证使用较少的 Atlas 的同时,
还需要保证 Atlas之间不会存在交叉遮挡。


要注意UI Texture的使用,每个UITexture自身会占用一个Draw Call,同时如果其Depth值穿插在了其他来自相
同Atlas的UISprite中,还会导致Draw Call的打断,造成不必要的额外Draw Call。


另外还可以借助Panel Tool和Draw Call Tool来对UI部分的Draw Call进行分析,前者可以显示每个UIPanel包含
了多少个Draw Call,而后者可以显示每个Draw Call由哪些UIWidget组成。"

其实我们只要抓住主要矛盾就可以解决问题,内存优化需要具体问题具体分析,Unity程序主要分为三部分:


以上三部分在前面给读者介绍过,这里只是列举了一下,将Unity打包后可以看到这三部分内容。


版权声明:本文为博主原创文章,未经博主允许不得转载。

诺贝尔奖史上的一些错误

就是法官也会出错Keay Davidson, 科学史作家2001年10月8日,星期一翻译:neweroica(yangwang2008(at)gmail.com)如果你想获诺贝尔奖,那么根据历史经验,...
  • neweroica
  • neweroica
  • 2007年06月30日 23:58
  • 2946

Unity 自动内存管理

 了解自动内存管理 When an object, string or array is created, the memory required to store it is allocat...
  • czlilove
  • czlilove
  • 2014年04月27日 19:43
  • 988

小数在内存中的存储表示

整数在内存中的存储方式比较简单,我们来看看小数在内存中的存储方式。首先,要学会十进制小数与二进制小数之间的转换。     (1)二进制小数转化为十进制小数       比如把二进制小数110.11转化...
  • ACdreamers
  • ACdreamers
  • 2014年02月09日 20:03
  • 9030

34 小数在内存中是如何存储的

小数在内存中是如何存储的
  • czg13548930186
  • czg13548930186
  • 2017年05月30日 08:35
  • 1486

揭秘腾讯核心技术:50位专家的纯干货分享

揭秘腾讯核心技术:50位专家的纯干货分享 腾讯公司——互联网三大巨头之一,旗下产品QQ和微信全球上亿用户量,公司有非常优秀的技术、设计、营销,产品运营团队。本文集整理50位腾讯技术人员对外分...
  • chengying332
  • chengying332
  • 2015年04月03日 09:17
  • 341

[雨松MOMO] Unity数据存储路径总结

一.在项目根目录中创建Resources文件夹来保存文件。 可以使用Resources.Load("文件名字,注:不包括文件后缀名");把文件夹中的对象加载出来。 注:此方可实现对文件实施“增删查...
  • z9895512
  • z9895512
  • 2015年06月30日 09:43
  • 522

揭秘内存中海量数据精确索引的秘诀

点击上方蓝字进行关注的都是靓仔和仙女呦索引的概念什么是索引索引是由用户创建,能够被修改和删除的,实际存储在数据库中的物理存在,它是某一个表中【一列或者若干列】值的集合和相应的指向表中物理标志这些值的数...
  • TVwR8OfV0P
  • TVwR8OfV0P
  • 2018年01月03日 00:00
  • 508

unity内存减少方法集合

本文集合了网上许多关于U3D内存减少方法的说发。博主未进行考证测试,仅仅收集以备用。 GarbageCollectAssetsProfile: 1.引擎在执行UnloadUnusedAssets...
  • alayeshi
  • alayeshi
  • 2016年09月23日 17:16
  • 1332

unity3d 获取使用内存大小 android and ios

获取的是应用在移动设备上面的实时允许是的进程使用内存大小和你直接在移动设备上查看进程的内存使用一模一样,绝对精确,废话不说上代码,你懂的 C# public static int GetUseM...
  • qqo_aa
  • qqo_aa
  • 2017年11月09日 14:13
  • 299

《CSS揭秘》案例

1.半透明边框   border: 10px solid hsla(0,0%,100%,.5); background: white; background-clip: padding-box; ...
  • ann295258232
  • ann295258232
  • 2016年09月19日 11:52
  • 876
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Unity内存存储揭秘
举报原因:
原因补充:

(最多只允许输入30个字)