net中使用了垃圾回收机制(GC)功能

在 .NET 中,垃圾回收(GC)是全自动、非确定性、分代式、压缩式的内存自动释放机制。
面试只要能把下面 9 句话讲清,就足以让面试官点头。

1. 谁负责

CLR 的 Garbage Collector (GC) 独占线程,程序员无法主动启动或终止,只能“建议”(GC.Collect 默认会被延迟/忽略)。

2. 回收什么

只回收托管堆(Managed Heap)上的内存;
非托管资源(句柄、Socket、DB 连接)必须自己释放(Dispose/Finalizer)。

3. 分代策略(Generational)

托管堆逻辑上分成三代:
  • Gen0 – 最新分配,每次 GC 必扫;
  • Gen1 – 0 次幸存,充当“缓冲带”;
  • Gen2 – 多次幸存,_full GC 才扫;
    对象越大(≥85 000 B)直接进入 LOH(Large Object Heap),Gen2 才检查,不压缩(.NET 4.5 起可可选压缩)。

4. 根(Roots)与可达性

GC 从全局/栈/寄存器里的 根引用出发,图遍历标记“可达”;
不可达 = 垃圾,标记结束后统一回收或压缩。

5. 工作流程(单线程简化版)

  1. Suspend 托管线程 →
  2. Mark 可达对象 →
  3. Relocate 更新引用地址 →
  4. Compact 把幸存对象挤到连续空间 →
  5. Resume 线程并修复指针。
Server GC 模式下,每个 NUMA 节点一个专用 GC 线程,可与用户线程并行(Background GC)。

6. 触发时机(非确定)

  • Gen0 预算用完;
  • 分配大对象 LOH;
  • 系统物理内存告急;
  • 显式 GC.Collect(不推荐);
  • AppDomain / 进程卸载。

7. 程序员能干预什么

  • IDisposable + using —— 尽早释放非托管资源;
  • GC.SuppressFinalize(this) —— 告诉 CLR 跳过 Finalizer,避免一次额外晋升;
  • GCSettings.LatencyMode —— 短时间切换到低延迟(游戏、金融行情);
  • GCHandle —— 人工保持引用或钉住(Pin)内存供非托管代码访问。

8. 性能指标

  • % Time in GC = GC CPU 时间 / 进程 CPU 时间,< 5 % 健康;
  • Gen0/Gen1/Gen2 回收次数比值,理想 100:10:1;
  • Promotion Rate 过高说明内存压力或对象生存期过长。

9. 常见面试快问快答

表格
复制
问题一句话标准答案
GC 会立即执行吗? 不会,非确定性,由 CLR 按需触发。
能在构造器里 GC.Collect 强制释放吗? 语法可以,实际会被延迟或忽略,别这么写。
结构体会被 GC 吗? 不会,值类型随栈帧或容器释放,不受 GC 管理。
什么对象一定进入 Gen2? LOH 大对象 和多次幸存的普通对象。
Dispose 与 Finalizer 区别? Dispose 显式、确定性;Finalizer 是GC 后的保底,调用时机不可控。
posted @ 2025-10-13 18:04  yinghualeihenmei  阅读(11)  评论(0)    收藏  举报