3分钟搞懂UnityGC垃圾回收

本文介绍了C#中的内存管理,包括如何通过重复使用对象、避免频繁GC、使用非分配函数、对象池和减少Debug日志来降低垃圾生成,从而提升大型项目性能。
摘要由CSDN通过智能技术生成

简述

  • 当用 new创建了对象,而后面的流程中这个对象没有被重复使用,意味着这个对象在语句执行完后就变成了垃圾,C#中的GC就是在某些时候集中去清理这些垃圾的,对于大型项目来说,这会造成比较大的开销,影响性能
  • 解决的办法 就是在最开始就 new 一个对象,然后后面的流程有需要就重复使用这个对象就好,不要每次使用的时候都要 new 一个来导致 GC
  • GC是处理 上的内存的,原理是如果 堆 上的内存差不多被丢满了的话,GC就会出手回收没有被重复利用的内存,所以要避免多次在 堆 上放内存

代码手动回收

  • System.GC.Collect()

如何避免常见的GC

  1. 在Update中使用射线检测时,会疯狂创建数组,会产生GC

    void Update() {
        Physics.RaycastAll(new Ray());
    }
    

    可以使用 Physics.RaycastNonAlloc避免,下面只创建了一次数组

    private RaycastHit[] hits = new RaycastHit[10];
    void Update() {
        Physics.RaycastNonAlloc(new Ray(), hits);
    }
    
  2. 协程

    • 当使用yield return 的时候也会产生一个新的对象

      IEnumerator Wait() {
          // 协程返回会创建一个引用类型数据
          yield return new WaitForSeconds(5f);
      }
      

      可以用 多个协程使用同一个对象来解决问题

      private WaitForSeconds delay = new WaitForSeconds(5f);
      IEnumerator Wait() {
          // 协程返回会创建一个引用类型数据
          yield return delay;
      }
      

      可以写一个具体的 YieldHelper 做为一个工具类,来具体处理协程提前应该创建好的变量,进而消除协程的GC

      // yield 的意思是产出
      IEnumerator WaitToDo(float setTime) {
          // 这里的堵塞逻辑其实是 
          yield return YieldHelper.WaitForSeconds(setTime);	
          // do something
      }
      
      public static class YieldHelper {
          public static IEnumerator WaitForSeconds(float totalTime) {
              float time = 0;
              while (time < totalTime) {
                  time += Time.deltaTime;
                  yield return null;		// 等待一帧
              }
          }
      }
      
  3. 实例化对象

    • 实例化对象产生大量垃圾 Instantiate(new GameObject());
    • 解决手段是 使用对象池技术来解决这个问题
  4. Debug.Log() 究极内鬼

    • 只需要调用一次就可以产生 1.4kb 的垃圾…

    • 解决方法是 可以在最终整合版本的时候删掉,也可以在发布游戏前,关闭日志消息功能

       Debug.unityLogger.logEnabled = false;
      

最后,其实在游戏中产生垃圾并没有什么问题,主要问题是别高频率的产生垃圾,否则在大项目里的卡顿是非常频繁的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值