GC垃圾回收机制

托管堆:由Mono分配与管理。而托管的 意思是可以自动改变堆的大小,适应内存的需要,适合时机调用GC释放内存。


Unity内存管理机制

1、Unity存在2个内存管理区域,堆和堆栈,堆栈一般存储小和短暂的数据,堆存储大和时间长的数据
2、堆和堆栈之间差异:堆栈分配与回收较快。而堆在分配内时,先检查是否有内存,如果没有,将会进行GC,堆在GC后内存仍然不足时,将会申请内存,但是GC所释放的内存,将会留给Mono,而不会返还给操作系统。GC时,会暂停那些需要Mono内存分配的线程。其中在GC和内存的扩展时很慢
问题:对于Mono内存的申请机制不了解,就不知道为什么要先申请大内存的,然后再申请小内存
答:因为先申请小的内存,再去申请大的内存时候,空闲内存肯定是不够的,所以将会出发GC或者内存扩展


GC

1、值类型变量在堆栈内存上分配,其他类型变量在推内存上分配

函数结束,立即回收
void Func(){
    int a = 1;
}
函数结束,不会立即回收,需要等待GC
void Func(){
    List<int> lists = new List<int>();
}

2、相关的解决方法:

  • 常用的函数中 尽量不要去进行内存的分配,利用缓存代替,比如函数中分配数组,可以选择用在外部定义一个缓存数组
  • Unity的Update中分配内存会产生很大的内存垃圾,可以考虑设置定时或者判断减少产生内存分配函数的调用

常见的不必要的内存分配

1、字符串,字符串在C#是类,并且字符串在创建完后将不可被改变,一旦改变相当于创建了一个新的字符串对象,原来的将会废弃,可以直接采用StringBuilder拼接。并且Debug.Log会造成很大的内存垃圾

Debug.Log造成的内存垃圾

2、Unity某些函数会产生内存垃圾

  • 如果unity中函数返回数组,那么每次都会分配一个数组,如下的循环就是如此
void Func(){
    for(int i=0; i<mesh.normal.Lenght; i++){
        Vector3 vec = mesh.normal[i];
    }
}
  • 其中gameObject.name或者gameObject.tag, 都将返回字符串,这样会造成不必要的内存垃圾。其中gameObject.CompareTag()。可以有效的避免内存垃圾

装箱操作

1、装箱操作就是将值类型被用作引用类型之间的变换。比如我们向需要引用类型参数的函数传入值类型,这时将会触发装箱操作。
2、对于装箱操作,将会为值类型分配一个System.Object对象,这样就多了不必要的引用类型,从而造成不必要的内存消耗。


协程

1、如yield return 0将会触发装箱操作,利用yield return null代替
2、yield return new WaitForSeconds(1)每次将会创建一个新对象。所以我们可以提前缓存一个这样的对象,从而放置每次都new一个新对象。


其他情况

1、结构体Struct中如果包含引用类型变量,那么GC将会检查这个结构体。所以使用上需要注意
2、当一个对象内包含对另一个对象的引用,那么GC将不得不去检查 

public class Person{
    private Person neighbor;
    xxx
}

重构后, 最后通过Id得到相应的结果
public class Person{
    private int neighborId;
    xxx
}

 3、标记清除法,先暂停进程中所有线程,然后将所有对象全部标成垃圾,然后从根对象根据引用遍历然后纳入对象图中,最后没有被纳入对象图的对象将会被清除。

4、分代0/1/2 越新的对象代数越靠前,GC后未被清理的将会被纳入下一代,每一代的GC不同0/1/2分别对应100:10:1,代数越老越回收频率越低。

5、非托管资源怎么回收,可以放到析构函数中,但是析构函数的调用有不确定性,为了有效的回收资源,所以有了IDisposable接口,可以手动或者using回收非托管资源。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值