UGUI优化

1.4k words

Desc:

….

GC的优化

降低GC操作的方法:
1. 减少GC的运行次数
2. 减少单词GC的时间
3. 将GC的运行时间延迟,避免在关键时间触发,如加载场景的时候调用GC

实现策略:
1. 对游戏进行重构,减少堆内存的分配和引用的分配。更少的变量和引用会减少GC操作的检测个数
(栈中的内存也是通过虚拟机进行释放的,栈内存存放的遍历有着确定的释放时间(生命周期),在调用方法时,会在内存中分配对应的一块空间(栈帧),当方法调用结束后,对应的栈帧就会被释放掉)
引用
2. 降低堆内存分配和回收的频率,尤其是关键时隔
3. 分析GC操作和堆内存拓展的时间,使其按照可预测的顺序执行

减少内存的方法:
1. 缓存变量:
重复利用(减少重复获取组件的操作)
2. 减少逻辑调用:
堆内存分配最坏的情况是反复调用的函数中进行堆内存的分配,可以考虑增加时间间隔,或者属性值变化的时候执行(监听特定的属性值)
3. 清楚链表:
进行链表分配得到时候清楚链表,而不是不停的生成新的链表(结合对象池)
4. 对象池:
5. 字符串:
a. 字符串不可变
b. 进行加操作时,会新建一个新的的字符串去存储,旧的字符串被抛弃,这样会造成内存垃圾(之前看的一本书中提及)


源码截图
Image text
使用过的sb会被缓存下来留给后面使用
Image text
Image text
Image text
降低字符串影响的方式:
1) 减少不必要的字符串创建,配置表存储在数据表中,将所有常用的字符串存储在内存中
2) 减少不必要的字符串操作,比如一些描述性字符串和频繁修改的字符串变量,分为两个部分的组件(Text1:道具Name数量: Text2:XXX)
3) 使用stringBuilderClass函数,在执行toString()时,会重新分配一个字符串,因此只能省去中间状态的内存分配
4) 移除Debug.Log()等log日志函数的代码,不但影响内存垃圾的分配,还会浪费CPU空间
5) 协程,生成实体来管理协程
Image text
6) foreach循环,5.5以前的版本中,会生成内存垃圾,每次在堆内存中产生了一个System.Object 用来实现迭代循环操作
7) 函数引用,函数的引用,分配在堆内存中进行
8) LINQ和常量表达式。以装箱的方式实现,在使用的时候最好进行性能测试
9) 主动调用GC操作,如果知道堆内存在被分配后没有使用,可以主动调用GC(如场景切换或者读进度条的时候)

动静分离

基于Rebatch是以Canvas为单位,当Canvas下UI元素发生变化时,会引起整个Canvas的重构,其中会包括网格合并,网格重叠检测,层级排序等操作。对于同一个界面,我们可以再细分Canvas,把相对静态的、不会变动的UI放在一个Canvas里,而相对变化比较频繁的UI就放在另一个Canvas里,使得频繁变化的Canvas里只对自己的Canvas下的元素进行Rebatch,而节省掉另一个Canvas中不需要变化的元素的Rebatch计算。
只有同一个Canvas下的UI元素才有可能合批,在中间新增Canvas会打断合批,动静分离优化本质是DrawCall换重构耗时的权衡。
Rebatch是在Canvas.BuildBatch函数中进行,而在Unity 5.2版本后,已经对Canvas.BuildBatch做了优化,优化后使用子线程进行计算,已经很大程度缓解了主线程的压力,目前来说动静分离并没有那么需要关注了。
花桑

UI拼接的优化

针对高低端机型的优化

内存泄漏

UI贴图设置的优化

对象池

UI重建的场景

网格重构的优化

字体拆分

Alpha通道分离

UI事件如何统一

UI优化

UI框架

自定义组件

输入事件响应机制

基类

管理类