基本概念
- 托管堆:在 C# 中,对象的内存分配主要发生在托管堆上。当创建一个对象时,CLR 会在托管堆上为其分配一块连续的内存空间。
- 引用计数:引用计数是一种简单的内存管理方法,它通过记录每个对象被引用的次数来判断对象是否可以被回收。当引用计数为 0 时,对象就可以被回收。但 C# 的 GC 并没有采用这种方法,而是使用了标记 - 清除和分代回收算法。
标记 - 清除算法
这是 GC 的核心算法之一,主要分为两个阶段:标记阶段和清除阶段。
标记阶段
- 根对象:GC 会从一组根对象开始,根对象是指那些始终可达的对象,例如全局变量、静态变量、当前执行方法的局部变量等。
- 标记过程:GC 会遍历所有的根对象,并递归地标记所有从根对象可达的对象。被标记的对象表示它们仍然在被使用,不能被回收。
清除阶段
- 清除过程:在标记阶段完成后,GC 会遍历整个托管堆,将所有未被标记的对象视为垃圾对象,并回收它们所占用的内存空间。
分代回收算法
C# 的 GC 采用了分代回收的策略,将对象分为不同的代(Generation),目前有三代:第 0 代(Gen 0)、第 1 代(Gen 1)和第 2 代(Gen 2)。
代的划分原则
- 第 0 代:新创建的对象通常被