Home Gc
Post
Cancel

Gc

什么是GC

  1. 游戏运行的时候,数据主要存储在内存中,当游戏数据不再需要的时候,当前这部分内存就可以被回收,以便再次利用。内存垃圾指当前废弃数据所占用的内存,GC是指将废弃的内存进行回收,使其可以再次被使用的过程。
  2. 垃圾回收器只回收内存,不回收其他资源,如:数据库连接,文件句柄,网络端口,硬件设备等。

GC原理

  1. mark-and-compact算法,mark是指先确定所有可达对象,compact是指移动这些对象,使它们紧挨着存放。整个过程有点儿像磁盘碎片整理。

终结器 Finalizer

  1. GC 负责为对象实例调用终结器。不能在编译时确定终结器的执行时间,唯一确定的是终结器会在对象最后一次使用之后的某个时间点调用。
  2. 确定性终结见:[[CS-using#自动释放资源]]
  3. 终结器很可能永远不会被调用
  4. 终结器在对象被 GC 判定为不可达的某个时间点执行,执行后再将其从终结队列中删除,使其可以再次使用。
  5. 终结器不负责回收内存。终结器负责释放文件句柄之类的资源。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    public class FileStream
    {
     // 构造函数
     public FileStream() {}
     // 声明终结器的语法和C++的析构器完全一致
     ~FileStream()
     {
         // todo something
     }
    }
    

内存垃圾太多会导致的问题

  1. GC调用越频繁,耗费CPU越多。
  2. GC调用频繁,会导致内存命中率下降。
  3. 堆内存碎片会导致占用内存越来越大,GC操作更加频繁。

GC触发时机

  1. 如果申请堆内存,堆内存不够,就会触发GC操作来回收闲置的内存。
  2. 各个平台会定时自动触发GC。

主动触发一次GC

1
System.GC.Collect();

怎样减少GC

  1. 缓存对象,不要在 Update 中频繁GetComponent。
  2. 减少逻辑调用。每帧调用变成隔一秒调用等。
  3. 复用 List,缓存下来,使用 Clear 清空,而不是 new 一个新的。
  4. 使用对象池。
  5. 字符串使用要格外小心,text要赋值的字符串尽量做到最短,把变化的数值独立出来。
  6. 减少字符串的使用,如果字符串拼接操作比较多,使用 [[CS-StringBuilder]]。
  7. 正式版移除 Debug.Log(),它不但分配字符串,还不间断的往文件写数据。
  8. 不要使用 LINQ。
  9. 使用公用的静态成员对象。
  10. 减少装箱和拆箱。
This post is licensed under CC BY 4.0 by the author.
Contents