unity内存减少方法集合

原创 2016年09月23日 17:16:04

本文集合了网上许多关于U3D内存减少方法的说发。以及自己总结的方法;


图片类:

(1)纹理格式选择

下图中 format 选项:Android平台选ETC、iOS平台选PVRTC、Windows PC上选DXT等等

ETC1 不支持透明通道---RGB格式
ETC2 支持透明通道-----是RGBA的格式
ETC后面都有个bit,bit越小图片质量越差,bit就根据情况来选择了
这两种都是安卓平台的图片格式,具体选择哪种要根据情况来选择。ios平台暂时没研究。


(2) Mipmap功能要关闭

Mipmap旨在有效降低渲染带宽的压力,提升游戏的渲染效率。但是,开启Mipmap会将纹理内存提升1.33倍。对于具有较大纵深感的3D游戏来说,3D场景模型和角色我们一般是建议开启Mipmap功能的,但是经常会发现部分UI纹理也开启了Mipmap功能。这其实就没有必要的,绝大多数UI均是渲染在屏幕最上层,开启Mipmap并不会提升渲染效率,反倒会增加无谓的内存占用。

(3) Read & Write
纹理资源的“Read & Write”功能在Unity引擎中是默认关闭的。开启该选项将会使纹理内存增大一倍。
Texture2D有个readwrite enable属性,这个属性的实质是决定了这个贴图的存放位置,是在内存上还是在显存上。(虽说在移动设备上显存和内存是共用的,但数据不直接互通) 如果可读写,那么这个贴图既在显存上,又在内存上,而且还必须得是非压缩的格式(ARGB32,ARGB4444之类)。用getPixel(s),setPixel(s)之类的方法,读取或设置的数据,都是内存上的数据,但其他属性不区分内存还是显存。Apply方法的作用是把这个贴图在内存上的传给显存。Apply方法的第二个参数,决定了这个这个贴图是否还可读写,换种说法就是内存上这部分数据在执行完这个方法之后还要不要
(关于图片的属性NON POWER OF 2等请看链接 http://blog.csdn.net/alayeshi/article/details/52958393)

代码方法减少内存:

1.引擎在执行UnloadUnusedAssets操作(该操作是比较耗时的,建议在切场景的时候进行).


2.尽可能地避免使用Unity内建GUI,避免GUI.Repaint过渡GC Allow.


3.if(other.tag == GearParent.MogoPlayerTag)改为other.CompareTag(GearParent.MogoPlayerTag).因为other.tag为产生180B的GC Allow.


F. 少用foreach,因为每次foreach为产生一个enumerator(约16B的内存分配),尽量改为for.


G. Lambda表达式,使用不当会产生内存泄漏.


H. 尽量少用LINQ:


1.部分功能无法在某些平台使用.


2.会分配大量GC Allow.


I. 控制StartCoroutine的次数:

1.开启一个Coroutine(协程),至少分配37B的内存.

2.Coroutine类的实例 — 21B.

3.Enumerator — 16B.


J. 使用StringBuilder替代字符串直接连接.

在Update方法或循环中,少用string类,因为string类的每次操作都会调用new生成新字符串对象。用StringBuilder代替string,StringBuilder基于固定Buffer操作,从而避免了内存的分配。


K. 缓存组件:

1.每次GetComponent均会分配一定的GC Allow.

2.每次Object.name都会分配39B的堆内存.




总结一下各种加载和初始化的用法:


AssetBundle.CreateFrom.....:创建一个AssetBundle内存镜像,注意同一个assetBundle文件在没有Unload之前不能再次被使用
WWW.AssetBundle:同上,当然要先new一个再 yield return 然后才能使用

AssetBundle.Load(name): 从AssetBundle读取一个指定名称的Asset并生成Asset内存对象,如果多次Load同名对象,除第一次外都只会返回已经生成的Asset 对象,也就是说多次Load一个Asset并不会生成多个副本(singleton)。


Resources.Load(path&name):同上,只是从默认的位置加载。
Instantiate(object):Clone 一个object的完整结构,包括其所有Component和子物体(详见官方文档),浅Copy,并不复制所有引用类型。有个特别用法,虽然很少这样 用,其实可以用Instantiate来完整的拷贝一个引用类型的Asset,比如Texture等,要拷贝的Texture必须类型设置为 Read/Write able。


总结一下各种释放


Destroy: 主要用于销毁克隆对象,也可以用于场景内的静态物体,不会自动释放该对象的所有引用。虽然也可以用于Asset,但是概念不一样要小心,如果用于销毁从文 件加载的Asset对象会销毁相应的资源文件!但是如果销毁的Asset是Copy的或者用脚本动态生成的,只会销毁内存对象。


AssetBundle.Unload(false):释放AssetBundle文件内存镜像
AssetBundle.Unload(true):释放AssetBundle文件内存镜像同时销毁所有已经Load的Assets内存对象
Reources.UnloadAsset(Object):显式的释放已加载的Asset对象,只能卸载磁盘文件加载的Asset对象
Resources.UnloadUnusedAssets:用于释放所有没有引用的Asset对象
GC.Collect()强制垃圾收集器立即释放内存 Unity的GC功能不算好,没把握的时候就强制调用一下

在3.5.2之前好像Unity不能显式的释放Asset


销毁时:
对Instantiate的对象进行Destroy
在合适的地方调用Resources.UnloadUnusedAssets,释放已经没有引用的Asset.
如果需要立即释放加上GC.Collect()
这样可以保证内存始终被及时释放
只要你Unload过的AssetBundle,那些创建的对象和引用都会在LoadLevel时被自动释放


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

关于Unity内存优化,你可能遇到这些问题

一、内存使用 Q1:在Unity的内存管理机制中, Reserved Total 和 Used Total之间的关系是怎样的? Reserved Total 和 Used Total为...
  • GTOFEI013
  • GTOFEI013
  • 2017年03月06日 16:21
  • 3655

Unity性能优化之内存篇(上)

项目的性能优化主要围绕CPU、GPU和内存三大方面进行。接上期CPU优化专讲,我们本期和大家分享内存方面的优化心得。 无论是游戏还是VR应用,内存管理都是其研发阶段的重中之重。 然而,在我们测评过...
  • UWA4D
  • UWA4D
  • 2016年12月14日 18:45
  • 5112

Unity3d-MMO游戏优化经验分享沙龙总结

原文地址:MMO游戏优化经验分享沙龙总结昨天去上海参加了UWA公司的张鑫和张强进行了一场关于MMO游戏开发和性能优化的沙龙,活动链接为:UWA优化日上海站|传统MMO手游性能该如何突围?。虽然第二场场...
  • yudianxia
  • yudianxia
  • 2018年02月10日 09:36
  • 148

【Unity3D】中如何分配内存占用(解决内存占用过大问题)

最近网友通过网站搜索Unity3D在手机及其他平台下占用内存太大. 这里写下关于Unity3D对于内存的管理与优化. Unity3D 里有两种动态加载机制:一个是Resources.Load,另...
  • swj524152416
  • swj524152416
  • 2017年02月10日 18:23
  • 2742

Unity mesh texture开启 read 会增加内存畅想

大家都知道,unity如果对 texture或者mesh开启了 read/write enable会增加一份拷贝在内存里。今天跟朋友讨论为何会增加,以及如何避免来着。大家都没看过unity的源码。所以...
  • nanhaibuluo
  • nanhaibuluo
  • 2016年05月14日 19:23
  • 1102

unity3d 代码设置贴图Read/Write Enable属性

[MenuItem("Image/SetReadWriteTrue")] static void SetReadWriteTrue() { Debug.LogWarning...
  • qq617119142
  • qq617119142
  • 2015年11月28日 17:36
  • 2472

Unity3D–Texture图片空间和内存占用分析

Unity3D–Texture图片空间和内存占用分析 发表于2014年5月21日由陆泽西 Texture图片空间和内存占用分析。由于U3D并没有很好的诠释对于图片的处理方式,所以很多人一直...
  • Highning0007
  • Highning0007
  • 2014年07月20日 13:13
  • 26125

android中,Bitmap类中的 setPixels比setPixel,显示一副图像速度快很多

public void setPixel (int x, int y, int color) 把指定的颜色写入到位图中x,y的坐标值的位置(假设该位图是可变的)。 参数 X     ...
  • yangxueping89
  • yangxueping89
  • 2015年11月10日 16:16
  • 704

Unity性能优化(主要是内存的优化)

Unity手游的性能优化过程更像是一门时空转换的艺术, 持续在CPU和内存之间取得一个平衡。空间不足时则需要释放一些无用数据,以获得更优的空间使用率;时间太长时就需要降低不必要的函数开销。以下是腾讯游...
  • u010377179
  • u010377179
  • 2016年10月25日 15:17
  • 2518

Unity性能优化---内存下

在上期的内存专题中,我们和大家分享了项目开发中的内存分配情况。除此之外,还有三个更为重要的地方需要研发团队关注:内存泄露、Mono无效堆内存开销和资源冗余。这几乎是所有团队在研发过程中都会遇到的问题。...
  • qq_26483719
  • qq_26483719
  • 2016年06月26日 19:24
  • 677
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:unity内存减少方法集合
举报原因:
原因补充:

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