最近在做项目内存优化,计划整理一个系列内容,本篇主要内容是Heap内存优化。
1】能显示Destroy的,就不要null
2】对频繁使用的对象,使用缓存池。
3】闭包,匿名函数,协程这些语法糖在最后都是一个一个的class,也是占内存的,建议使用的时候生产出来,不用了就释放掉。
比如sort(delegete(int a, int b)) 尽量改成
//先生产出来
private int SortFunc(int a, int b)
{
return a < b;
}
list.sort(SortFunc);
4】各种配置表分块按需加载。
5】频繁被调用的函数中尽量少的分配空间,尤其注意在Update()中使用string进行拼接,拆分等操作。
7】复用集合类变量,如List数据,当有新数据时Clear()后重新添加而不是new List()
8】Text组件文本若经常变化,可以考虑将不变的文本和变化的文本拆为多个Text组件
9】没用的debug要去掉或者定义宏仅在Editor中使用。
10】在循环结构中,避免相同内容不停的调用或者new。比如:
//这样
for(int i = 0, len = myList.Count; i < len; i++)
{
//do something
}
//这样
WaitForSeconds wait = new WaitForSeconds(1);
while(true)
{
yield return wait;
}
11】LINQ和正则表达式都会由于存在装箱而产生垃圾,对性能要求比较高时应避免使用它们。
12】struct结构是值类型,但当结构中包含引用类型时,垃圾回收器也不得不对整个结构进行检查,当有大的结构数组存在时就会加大垃圾回收的负担:
public struct ItemD
{
public string name; //引用类型
public int id;
}
private ItemD[] itemD;
13】类被引用的数量越多,垃圾回收需要检查的工作则越大,尽量减少没必要的类引用。
14】在一些切换场景,战斗结束等时机,主动GC
//安卓相比较ios,gc较慢,尽量少主动调用
System.GC.Collection();
15】避免使用过多static对象
16】值类型转换成引用类型时需要在堆上申请内存,注意使用。尤其是尽量不要用enum当dictionary的key。
17】避免重复调用unity api,因为每次调用会返回新的数据。
18】初始化string时,尽量使用string.Enpty 而不是 “”;
另外频繁new string 也是不好的,使用StringBuilder替换(命名空间是System.Text)
19】对于明确直到List长度的时候,初始化List的时候就明确给定长度,否则如果不够的时候,内存申请会申请很大(2的N次方级的申请)。
20】贴图相关
20.1】贴图设置为read,如果write的话,内存里会有一份拷贝
20.2】UI贴图勾选掉minimap
20.3】贴图合并为2的n次方大图