C# 中的垃圾回收(Garbage Collection, GC)机制是自动管理应用程序内存的一个重要组成部分,它自动跟踪和回收不再使用的对象所占用的内存。这一机制使得开发人员不必手动分配和释放内存,降低了内存泄漏的风险,提高了开发效率。以下是C#垃圾回收机制的几个关键方面:

堆内存管理

C#程序中的对象(即引用类型实例)存储在托管堆(managed heap)上。当创建一个对象时,.NET运行时会为其在堆上分配内存。而值类型,如果作为局部变量,通常存储在栈上;如果作为类或结构体的字段,则同样存储在堆上作为对象的一部分。

代际回收

.NET的垃圾回收器采用代际回收策略,将堆划分为三个代(Generation 0、1、2),每个代对应不同的回收频率和成本效益比:

  • Generation 0 (Gen 0): 新创建的对象首先被分配在这里。Gen 0的回收最频繁,因为它包含了短生命周期的对象。每次Gen 0回收都会检查并清理不再引用的对象。
  • Generation 1 (Gen 1): 经过一次Gen 0回收仍然存活的对象会被提升到Gen 1。Gen 1的回收频率低于Gen 0。
  • Generation 2 (Gen 2): 经过Gen 1回收仍存活的对象最终进入Gen 2。Gen 2的对象被认为是长寿对象,回收频率最低。

垃圾回收触发时机

垃圾回收的触发条件包括但不限于:

  • 当托管堆空间不足时。
  • 当系统资源紧张时。
  • 显式调用 GC.Collect() 方法(虽然不推荐,因为GC会根据需要自动执行)。

回收过程

  1. 标记阶段:GC首先执行标记操作,识别出所有可达的对象,即从根对象(如静态变量、线程栈上的局部变量)开始,遍历引用链,标记所有可达的对象。
  2. 压缩阶段(在某些回收周期中):回收结束后,为了减少堆碎片,GC可能会执行压缩操作,移动存活的对象,整理堆空间,使其连续。
  3. 清理阶段:未被标记的对象所占用的内存被回收,释放给堆使用。

非确定性延迟

垃圾回收的过程是不可预测的,这意味着它可能在任何时刻发生,导致应用程序暂停执行(停顿),这对于实时或高性能应用可能是个问题。.NET提供了低延迟的GC模式(如服务器GC模式)来减轻这个问题。

最后修改:2024 年 06 月 16 日
如果觉得我的文章对你有用,请随意赞赏