88.C#垃圾回收机制的方式

  1. 88.CSharp垃圾回收机制的方式
    1. 88.1 题目
    2. 88.2 深入解析
    3. 88.3 答题示例
    4. 88.4 关键词联想

88.CSharp垃圾回收机制的方式


88.1 题目

C#中的垃圾回收机制是使用的引用计数还是其它方式呢?


88.2 深入解析

采用 分代收集 + 标记-清除 + 压缩 的组合方式,具体流程如下:

  1. 分代收集
    基于对象的存活时间将堆划分为不同代(如第0、1、2代),优先回收存活时间短的对象(如第0代),减少每次回收的范围,提高效率。

  2. 标记
    从根对象(如全局变量、当前栈帧中的引用等)出发,沿引用图遍历所有被引用的对象,标记出可达对象(仍活跃的对象);未被标记的对象则视为垃圾,待后续清理。

  3. 清除
    释放所有未被标记的垃圾对象所占用的内存空间。

  4. 压缩
    主要用于解决内存碎片问题:将存活对象从堆的分散区域移动到连续区域,整理出大块连续的空闲内存,便于后续新对象的分配。


88.3 答题示例

“C#的垃圾回收机制采用的是分代收集 + 标记-清除-压缩算法,而非引用计数:
1. 分代收集(Generational GC)
将堆内存分为三代(Gen0/Gen1/Gen2),新对象优先分配在Gen0。频繁回收小对象所在的年轻代(Gen0/Gen1),减少全局GC频率。

2. 标记阶段(Mark)
从根对象(静态变量、线程栈、寄存器)开始遍历所有可达对象,标记仍在使用的对象。未被标记的对象被视为垃圾。

3. 清除阶段(Sweep)
释放未被标记对象占用的内存空间,将其添加到空闲列表。

4. 压缩阶段(Compact)
为解决内存碎片化问题,GC会将存活对象移动到连续内存区域,使空闲内存块合并为更大的连续空间。

与引用计数的对比

  • 引用计数(如Python)需为每个对象维护引用计数器,存在循环引用无法回收的问题
  • C#通过可达性分析(Reachability Analysis)解决了循环引用问题
  • 分代策略利用了“多数对象生命周期短暂”的特性,提升回收效率

优化建议

  • 减少短期对象的创建频率,降低Gen0 GC压力
  • 大对象(>85KB)直接分配在LOH,避免频繁触发Full GC
  • 使用弱引用(WeakReference)避免意外持有对象引用”

88.4 关键词联想

  • 可达性分析(Reachability Analysis)
  • 根对象(Root Objects)
  • 标记-清除-压缩(Mark-Sweep-Compact)
  • 内存碎片化(Fragmentation)
  • 代(Generation)
  • 大对象堆(LOH, Large Object Heap)
  • GC暂停(GC Pause)
  • 弱引用(WeakReference)
  • 终结器(Finalizer)
  • IDisposable接口
  • GC模式(工作站/服务器GC)
  • 对象晋升(Promotion)


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏