《unity游戏优化》第8章内存优化

发布于:2022-11-29 ⋅ 阅读:(163) ⋅ 点赞:(0)

内存管理性能增强

遇到性能问题可以将低效代码转移到更快的本地代码中

垃圾回收策略

触发回收的好时机是加载场景时,当游戏暂停时,再打开菜单界面后的瞬间

unity垃圾回收是使用标记清除来做的

拆箱和装箱

装箱:将值类型转换为引用类型称为装箱

拆箱:将引用类型转换为值类型称为拆箱

class Program
{
    static void Main(string[] args)
    {
        int i = 128;
        object obj = i;
        obj = 512f;
        i = (int)obj;
    }
    //尝试将obj拆箱到一个不是最新赋值的类型时,将引发
    //Unhandled exception. System.InvalidCastException: Unable to cast object of type 'System.Single' to type 'System.Int32'.

    
}

1.struct是指类型,class是引用类型

public class DamageResult {
 public Character attacker;
 public Character defender;
 public int totalDamageDealt;
 public DamageType damageType;
 public int damageBlocked;
 // etc.
}
public void DealDamage(Character _target) {
 DamageResult result = CombatSystem.Instance.CalculateDamage(this,
_target);
 CreateFloatingDamageText(result);
}

public struct DamageResult {
 // ...
}
//当使用目的是在向程序某处发送数据库,且数据的持续时间不需要超过
//当前作用域,那么可以使用struct来替代



2.数组的区别

TestStruct[] dataObj = new TestStruct[1000];
for(int i = 0; i < 1000; ++i) {
 dataObj[i].data = i;
 DoSomething(dataObj[i]);
}
However, the following, functionally equivalent, code would not result in any heap
allocations since the struct objects being used are value types, and hence, it would be
created on the stack:
for(int i = 0; i < 1000; ++i) {
 TestStruct dataObj = new TestStruct();
 dataObj.data = i;
 DoSomething(dataObj);
}
void TestFunction() {
    string testString = "Hello";
    DoSomething(testString);
    Console.WriteLine(testString);
    //Debug.Log(testString);
}
void DoSomething(string localString) {
    localString = "World!";
}


TestFunction();
这个代码还是打印hello


1.通过值传递值类型,只能修改其数据的副本值

2.通过引用传递值类型,可以修改传入的原始数据

3.通过值传递引用类型,就可以修改原始引用的对象

4.通过引用传递引用类型,可以修改原始的引用的对象数据集

3.数据布局的重要

public struct MyStruct {
 int myInt;
 float myFloat;
 bool myBool;
 string myString;
}
MyStruct[] arrayOfStructs = new MyStruct[1000];


对比
int[] myInts = new int[1000];
float[] myFloats = new float[1000];
bool[] myBools = new bool[1000];
string[] myStrings = new string[1000];

4.对字典键使用obj.GetInstanceID();

5.unity api中的数组开销

int[] myInts = new int[1000];

float[] myFloats = new float[1000];

bool[] myBools = new bool[1000];

string[] myStrings = new string[1000];

6 foreach巡回会在堆上分配一个Enummerator的类,而不是堆上分

7.协程会消耗少量内存,直到调用yield,避免产生太多短信时间的协成

8.闭包很危险,匿名方法和lambda表达式可以是闭包,但不能总是闭包,取决于方法是否使用了它的作用于和参数列表之外的数据

9..net库要少用,比如lINQ和Rehhex类,因为 通用必定减低性能

10.对象池,预制池

本文含有隐藏内容,请 开通VIP 后查看