专栏首页WeTest质量开放平台团队的专栏[分享干货晒技术]Unity 手游内存优化分享

[分享干货晒技术]Unity 手游内存优化分享

这里从三个纬度来分享下内存的优化经验:代码层面、贴图层面、框架设计层面。

一.代码层面。

1.foreach。

Mono下的foreach使用需谨慎。频繁调用容易触及堆上限,导致GC过早触发,出现卡顿现象。

特别注意的是在Update中如果非必要,不要使用foreach。尽可能用for来代替foreach。会产生GC Alloc,说明foreach调用GetEnumerator()时候有堆内存上的操作,new和dispose。

2.string修改。

如果熟悉C++的话,就会了解,每次使用string的时候,都要在内存中创建一个新的字符串对象,就需要为该新对象分配新的空间。 特别是在循环中需要修改string对象,就会频繁的分配新的空间,这时候推荐使用StringBuilder.Append等操作来处理。C++中通常也是通过分配一个固定的字符内存来处理字符串的操作。

3.gameObject.tag

gameObject.tag 会在内部循环调用对象分配的标签属性以及拷贝额外的内存,推荐使用gameObject.CompareTag("XXX")来代替.tag。

4.使用ObjectPool对象池来管理对象,避免频繁的Instance,Destroy。

二.贴图层面。

代码上的内存优化,很大层面上都不及贴图上的优化。有时候改一张图就帮你省了大几兆的内存。

1.巧妙通过调整纹理资源,来调整图的大小。比如:通过9宫格、部分缩小后Unity里在拉大等方式。

比如:(主要调整了两个小元素)就省了一半的内存。

优化前

优化后 2.Ios平台使用PVRT压缩纹理。Adroid平台使用ETC1格式压缩。均可以减至1/4的内存大小。优化非常明显。

目前主流的Android机型基本都支持ETC1格式压缩。但ETC1只能支持非Alpha通道的图片压缩。所以一般把Alpha通道图分离出来,绘制到GPU显存时,a值从Alpha图里获取,无Alpha通道的图就可以使用ETC1压缩。

而ETC2以上的格式压缩虽然支持含Alpha通道的图片,但是支持的机型还比较少。目前不推荐使用。

未使用ETC1压缩前的内存占用大小1024*1024的png图占用10.7M(包含了Editor中的内存占用,以及mip map内存占用)。

mipMap是摄像机离得远近用不同的图片,3D游戏中用内存换性能的一种有效方式。它会将大图变成若干小图,存储内存中,当摄像机离的比较远的时候,只需使用小图。

UI、2D场景可以把Texure这个设置去掉。

这样实际游戏中未压缩纹理1024×1024的图在内存中占用是 4M。(Unity Profiler下看应该是8M)

使用ETC1压缩后,场景图片一张大小只有1.3MB,加上通道图2.6M。几乎是用来的1/4。

甚至文件的大小也小了1/4。

3.通过减色的方式减少图片大小。很多UI其实使用的色彩很少,用不到256色。这类图片就可以进行减色压缩。

三.框架设计层面。

一个相对中大型的游戏,系统非常的多。这时候合理的适时的释放内存有助于游戏的正常体验,甚至可以防止内存快速到达峰值,导致设备Crash。

目前主流平台机型可用内存:

Android平台:在客户端最低配置以上,均需满足以下内存消耗指标(PSS):

1)内存1G以下机型:最高PSS<=150MB

2)内存2G的机型:最高PSS<=200MB

iOS平台:在iPhone4S下运行,消耗内存(real mem)不大于150MB

1.场景切换时避开峰值。

当前一个场景还未释放的时候,切换到新的场景。这时候由于两个内存叠加很容易达到内存峰值。解决方案是,在屏幕中间遮盖一个Loading场景。在旧的释放完,并且新的初始化结束后,隐藏Loading场景,使之有效的避开内存大量叠加超过峰值。

2.GUI模块加入生命周期管理。

主角、强化、技能、商城、进化、背包、任务等等。通常一个游戏都少不了这些系统。但要是全部都打开,或者这个时候再点世界地图,外加一些逻辑数据内存的占用等等。你会发现,内存也很快就达到峰值。

这时候有效的管理系统模块生命周期就非常有必要。首先将模块进行划分:

1)经常打开 Cache_10;

2)偶尔打开 Cache_5;

3)只打开一次 Cache_0。

创建一个ModuleMananger 类,内部Render方法每分钟轮询一次。如果是“Cache_0”这个类型,一关闭就直接Destroy释放内存;“Cache_10”这个类型为10分钟后自动释放内存;" Cache_5"这种类型为5分钟后自动释放内存。每次打开模块,该模块就会重新计时。这样就可以有效合理的分配内存。

本文转载自GAD社区(gad.qq.com)

本文分享自微信公众号 - 腾讯WeTest(TencentWeTest)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2015-07-31

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 实战PerfDog优化小游戏性能

    背景: 我们的引擎是Egret,使用的是原生的EUI,转微信小游戏; 工程第一版出来后使用PerfDog测试一波数据。结果发现很多问题,本文主要分两部分

    WeTest质量开放平台团队
  • Perfdog玩转内存泄漏

    最近QC同学在跑游戏的过程中发现玩的时间久了游戏会发生闪退,经过搜集信息后排除了功能性bug的

    WeTest质量开放平台团队
  • UPA深度性能报告解读

    UPA作为腾讯WeTest与Unity官方联合打造的客户端性能分析工具,为开发者提供了极大的便利和效能提升。产出的分析报告内容详尽,但您是否真的读懂了报告?是否...

    WeTest质量开放平台团队
  • 剑指内存泄漏

    指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,失去了对该段内存的控制,因而造成了内存的...

    audy
  • SQL Server内存

    背景 最近一个客户找到我说是所有的SQL Server 服务器的内存都被用光了,然后截图给我看了一台服务器的任务管理器。如图 ? 这里要说明一下任务管理器不会完...

    用户1217611
  • 故障分析 | MySQL OOM 故障应如何下手

    前阵子处理这样一个案例,某客户的实例 mysqld 进程内存经常持续增加导致最终被 OOM killer。作为 DBA 肯定想知道有哪些原因可能会导致 OOM(...

    爱可生开源社区
  • zephyr笔记 2.3.2 内存池

    内存池是一个内核对象,它允许从指定的内存区域动态分配内存块。 内存池中的内存块可以具有任意大小,从而在应用程序需要为不同大小的数据结构分配存储空间时减少浪费的内...

    twowinter
  • iOS内存优化心得

    当app经过一段儿时间的迭代,往往会出现一些性能问题,这时能够协助开发同学解决这些性能问题也成为我们测试同学的重要工作。凑巧最近一段时间小编就一直在协助开发同学...

    用户5521279
  • 虚拟内存详解

    究其原因,监控系统计算的可用内存算法有偏差,他只关注了计算机的“实际”内存,忽略了计算机的虚拟内存。

    bisal
  • 软件性能测试(连载9)

    Linux内核给每个进程都提供了一个独立的虚拟地址空间,并且这个地址空间是连续的。Linux的空间又分为内核空间和用户空间,在32位中,内核空间占1G,用户空间...

    小老鼠

扫码关注云+社区

领取腾讯云代金券