2023-05-08
编程语言
00

目录

一、GC 的目的
二、GC的回收流程
三、GC 的工作机制
1. 托管堆(Managed Heap)
2. 代际回收机制(Generational Collection)
3. GC 的触发条件
四、常用 GC API
五、如何避免频繁触发GC

一、GC 的目的

垃圾回收器(Garbage Collector,简称 GC)是 .NET CLR(公共语言运行时)中的一项重要机制,用于自动管理内存。其主要职责:

  • 自动释放不再使用的对象内存
  • 防止内存泄漏
  • 避免使用已释放的对象

二、GC的回收流程

GC 回收大致分为三步:

  1. 标记(Mark):识别所有“根对象”可达的内存区域(静态字段、方法参数),从Root来开始检查那些是可达对象,那些是不可达对象,不可达对象标记为垃圾
  2. 清除(Sweep):清除不可达的对象,迁移可达对象到第+1代内存上,并修改引用地址
  3. 整理(Compact):压缩存活对象,消除内存碎片,不会对大对象进行压缩,83kb以上的对象是大对象

A_flowchart_in_the_digital_illustration_showcases_.png

随着GC触发的次数越多,对象迁移的次数也就越多,GC的成本就越高,因为高代(Gen2)内存上存储的对象就越大


三、GC 的工作机制

1. 托管堆(Managed Heap)

所有通过 new 创建的对象都存储在托管堆中,也就是堆内存都由 GC 管理。托管堆是连续内存区域,GC 会自动跟踪对象的生命周期。

2. 代际回收机制(Generational Collection)

也就是平时所说的分代回收,分代的计算方式

为提高效率,GC 将对象分为以下几代:

代(Generation)描述
第 0 代(Gen 0)新创建对象,生命周期短
第 1 代(Gen 1)从 Gen0 存活下来的中期对象
第 2 代(Gen 2)生命周期长的老对象,回收代价大

GC 更频繁地回收 Gen0,较少处理 Gen2。

3. GC 的触发条件

GC 会在以下场景触发:

  • 托管堆内存不足
  • 系统内存压力大
  • 手动调用 GC.Collect()
  • 应用程序空闲时间

四、常用 GC API

csharp
GC.Collect(); // 强制触发 GC GC.GetGeneration(obj); // 获取对象所处代 GC.GetTotalMemory(false); // 获取当前托管堆大小 GC.SuppressFinalize(obj); // 禁用对象的析构函数调用

五、如何避免频繁触发GC

  1. 复用对象(对象池)
  2. 轻量的生命周期短的对象,使用结构体代替类
  3. 减少闭包的使用

本文作者:xuxuxuJS

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!